Farmer John goes to Dollar Days at The Cow Store and discovers an unlimited number of tools on sale. During his first visit, the tools are selling variously for $1, $2, and $3. Farmer John has exactly $5 to spend. He can buy 5 tools at $1 each or 1 tool at $3 and an additional 1 tool at $2. Of course, there are other combinations for a total of 5 different ways FJ can spend all his money on tools. Here they are:
1 @ US$3 + 1 @ US$2Write a program than will compute the number of ways FJ can spend N dollars (1 <= N <= 1000) at The Cow Store for tools on sale with a cost of $1..$K (1 <= K <= 100).
1 @ US$3 + 2 @ US$1
1 @ US$2 + 3 @ US$1
2 @ US$2 + 1 @ US$1
5 @ US$1
Input
A single line with two space-separated integers: N and K.
Output
A single line with a single integer that is the number of unique ways FJ can spend his money.
Sample Input
5 3
Sample Output
5
完全背包+高精度数
没有优化直接wa,是数值范围太小
#include<iostream> using namespace std; int dp[105][1005]; int main(){ int n,k; cin>>n>>k; dp[0][0]=1; for(int i=1;i<=k;i++){ for(int j=0;j<=n;j++){ for(int k=0;k*i<=j;k++){ dp[i][j]+=dp[i-1][j-k*i]; } } } cout<<dp[k][n]; return 0; }
改用unsigned long long还是wa。那就用两个unsigned long long一个存低位一个存高位。unsigned long long的范围是1844674407370955161,所以用一个比它小一个数量级的数,
100000000000000000。
#include<iostream> using namespace std; unsigned long long dp[105][1005][2]; #define LIMIT_ULL 100000000000000000 int main(){ int n,k; cin>>n>>k; dp[0][0][1]=1;//低位 for(int i=1;i<=k;i++){ for(int j=0;j<=n;j++){ for(int k=0;k*i<=j;k++){ dp[i][j][1]+=dp[i-1][j-k*i][1]; dp[i][j][0]+=dp[i-1][j-k*i][0]; dp[i][j][0]+=dp[i][j][1]/LIMIT_ULL;//低位的进位加到高位 dp[i][j][1]=dp[i][j][1]%LIMIT_ULL;//低位去除进位 } } } if(dp[k][n][0]){ cout<<dp[k][n][0]; } cout<<dp[k][n][1]; return 0; }
以上比你不是最优的,可能会TLE
dp[i][j]+=dp[i-1][j-i*k]可以优化成dp[i][j]=dp[i-1][j]+dp[i-1][j-k]
因为当k>1时的计算结果,已经保存在了dp[i-1][j-k]
#include<iostream> using namespace std; unsigned long long dp[105][1005][2]; #define LIMIT_ULL 100000000000000000 int main(){ int n,k; cin>>n>>k; dp[0][0][1]=1; for(int i=1;i<=k;i++){ for(int j=0;j<=n;j++){ if(j<i){ dp[i][j][1]=dp[i-1][j][1]; dp[i][j][0]=dp[i-1][j][0]; } else{ dp[i][j][1]=dp[i-1][j][1]+dp[i][j-i][1]; dp[i][j][0]=dp[i-1][j][0]+dp[i][j-i][0]; dp[i][j][0]+=dp[i][j][1]/LIMIT_ULL; dp[i][j][1]=dp[i][j][1]%LIMIT_ULL; } } } if(dp[k][n][0]){ cout<<dp[k][n][0]; } cout<<dp[k][n][1]; return 0; }