题目:
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$2 1 @ US$3 + 2 @ US$1 1 @ US$2 + 3 @ US$1 2 @ US$2 + 1 @ US$1 5 @ US$1
Write 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).
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
题意:
给我们两个数字,第一个是我们的金额,第二个代表从有1-m种金币,问由这些货币能组成现在第一个金额的组成方式。
解题思路:
完全背包+大数 因为数据范围会爆 long long 所以咱们开了二维的dp,dp[x][0]存放大数的前半段,dp[x][1]存放后半段,最后输出大树的前半段就好。
ac代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 2100
#define LIMIT_ULL 100000000000000000
using namespace std;
typedef long long ll;
ll dp[1005][2];
int main()
{
int n,k;
while(scanf("%d%d",&n,&k)==2)
{
memset(dp,0,sizeof(dp));
dp[0][1]=1;
for(int i=1;i<=k;i++)
for(int j=i;j<=n;j++)
{
if(dp[j-i][1])
{
dp[j][0]+=dp[j-i][0];
dp[j][1]+=dp[j-i][1];
dp[j][0]+=dp[j][1]/LIMIT_ULL;
dp[j][1]=dp[j][1]%LIMIT_ULL;
}
}
if(dp[n][0])
{
cout<<dp[n][0];
}
cout<<dp[n][1]<<endl;
}
return 0;
}