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:
Input
1 @ US$3 + 1 @ US$2 1 @ US$3 + 2 @ US$1 1 @ US$2 + 3 @ US$1 2 @ US$2 + 1 @ US$1 5 @ US$1Write 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).
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 3Sample Output
5
PS:首先题中提到了1到K的钱可以任意使用,可以得出这是一个完全背包,还有最后这个数已经达到了32位,所以用两个long long 数组来存。状态转移方程,可声明一个二维数组dp[i][j],表示用了i种额度的钱,在数目为j的钱的最多组合数目。由题可得,能组成当前钱的组合,一定是前一个钱数的组合加上一个额度的钱得到的。所以得到状态转移方程dp[j]+=dp[j-i];。这里还有一个类似的题。比这个简单一点。https://blog.csdn.net/qq_41292370/article/details/80989982
#include <iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<string>
#include<map>
const int maxn=1e3+5;
const long long mod=1e16;
#define me(a) memset(a,0,sizeof(a))
#define ll long long
using namespace std;
long long dp[maxn],dp1[maxn];
int main()
{
int n,k;
cin>>n>>k;
me(dp),me(dp1);
dp[0]=1;
for(int i=1;i<=k;i++)
for(int j=1;j<=n;j++)
if(j>=i)
{
dp[j]+=dp[j-i];
dp1[j]+=dp1[j-i];
dp1[j]+=dp[j]/mod;
dp[j]%=mod;
}
if(dp1[n])
cout<<dp1[n];
cout<<dp[n]<<endl;
return 0;
}