赞
踩
假设货币面额有1,2,4,5,10,每种数量都无限多,现在给出金额n(1<=n<=100000),求出最少使用多少张货币。
此时则不可以用贪心算法,而是应该用动态规划。因为此时前n-1项之和不再小于第n项的值,所以贪心不再成立。例如:8元如果用贪心查找,每次都选最大的,那我们找不到解,而实际上可以用两张4元就可以解决。
int main() { vector<int> v = { 1,2,4,5,10}; int n; cin >> n; int dp[n+1]; for(int i = 0; i <= n; i++){ dp[i] = i; // 初始化为i。任意金额都可以由一元组成 } for(int i = 0; i < v.size(); i++){ dp[v[i]]= 1; // 如果当前金额为现有货币币种,那一张就够。 } for(int i = 1; i <= n; i++){ for(int j = 0; j < v.size(); j++){ if(v[j] > i) continue; dp[i] = min(dp[i], dp[i-v[j]] + 1); // 当前金额i是否可以通过一张面额为v[j]的币种和金额为i-v[j]的数量组成更小的张数。 } } cout << dp[n] << endl; }
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
如果台阶级数大于2,设为n的话,这时我们把n级台阶时的跳法看成n的函数,记为f(n),有:
int jump(int n) {
if (n <= 2) {
return n;
} else {
return jump(n-1)+jump(n-2);
}
}
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
int jump2(int n) {
if (n <= 1) {
return 1;
} else {
return 2 * jump2(n - 1);
}
}
可通过画递归树来求解递归式,得出直接计算的公式。
// 一般解法 int nums[201]; // 数组 int dp[201]; // dp[i]:以ai结尾的最长子序列长度 int count[201]; // count[i]:以ai结尾的LIS个数 int main() { int T; cin >> T; while (T--) { int n; cin >> n; for (int i = 1; i <= n; ++i) { cin >> nums[i]; dp[i] = 1; count[i] = 1; } int max = 1, result = 0; for (int i = 1; i <= n; ++i) { for (int j = 1; j < i; ++j) { // 不需要求个数 // if (nums[i] > nums[j] && dp[i] <= dp[j]) // dp[i] = dp[j] + 1; if (nums[i] > nums[j]) { if (dp[i] < dp[j] + 1) { dp[i] = dp[j] + 1; count[i] = count[j]; } else if (dp[i] == dp[j] + 1) { count[i] += count[j]; } } } if (dp[i] > max) max = dp[i]; } for (int i = 1; i <= n; ++i)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。