UVA-10313
Posted shuiyonglewodezzzzz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA-10313相关的知识,希望对你有一定的参考价值。
题意:从1-N种硬币,每个硬币的面值是1-N,数量无限,问,给你面值K,使用总数为T枚的硬币,总共有多少种方案组合出K。
如果输入只有一个数K,表示使用0-K枚硬币组合出K
有俩个数K,N1,表示使用0-N1枚硬币,组合出K
如果有三个数K,N1,N2,表示使用N1-N2枚硬币,组合出K。
Sample Input
6
6 3
6 2 5
6 1 6
Sample Output
11
7
9
11
解题思路:
DP,dp[j][k] = dp[j][k]+dp[j-i][k-1]
dp[j][k] 的含义是 使用k枚硬币组合出j的方案数。
方程的含义是使用 1 枚面值为i的硬币 + 先前的总数。
注意生成dp数组的顺序,按照不重复枚举的顺序生成。
首先是全部使用1。然后是开始使用2,然后开始加入3,一直加入到N
这样就不会重复计算一样的方案数。
#include <string> #include<iostream> #include <sstream> #include<map> #include<memory.h> #include<vector> #include<algorithm> #include<queue> #include<vector> #include<stack> #include<math.h> #include<iomanip> #include<bitset> #include"math.h" namespace cc using std::cout; using std::endl; using std::cin; using std::map; using std::vector; using std::string; using std::sort; using std::priority_queue; using std::greater; using std::vector; using std::swap; using std::stack; using std::bitset; using std::stringstream; constexpr int N = 306; //const int N = 7; long long dp[N][N]; void init() memset(dp,0,sizeof(dp)); dp[0][0] = 1; for (int i=1;i<N;i++) for (int j=i;j<N;j++) for (int k=1;k<N;k++) dp[j][k] += dp[j-i][k-1]; void solve() string str; init(); while (getline(cin,str)) if (str.length() == 0) continue; stringstream sin(str); int n1=-1, n2=-1, n3=-1; sin >> n1; sin >> n2; sin >> n3; long long total = 0; if (n1!=-1 && n2!=-1 && n3!=-1) n2 = std::min(n2,300); n3 = std::min(n3, 300); for (int i = n2; i <= n3; i++) total += dp[n1][i]; else if (n1!=-1 && n2!=-1) n2 = std::min(n2, 300); for(int i=0;i<=n2;i++) total += dp[n1][i]; else for(int i=0;i<=n1;i++) total += dp[n1][i]; cout << total << endl; ; int main() #ifndef ONLINE_JUDGE freopen("d://1.text", "r", stdin); #endif // !ONLINE_JUDGE cc::solve(); return 0;
以上是关于UVA-10313的主要内容,如果未能解决你的问题,请参考以下文章