Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 4220 | Accepted: 1642 |
Description
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).
Input
Output
Sample Input
5 3
Sample Output
5
題意:輸入n,k表示有k種硬幣,價值是1~k,求用這些硬幣組合出價值n的方案數
解析:數值很大,64位裝不下,所以用兩個64位的分別充當高位和低位來解決,然後就是完全揹包問題了
*******這裏有個點我要說,雖然不算錯,但是這是題目的漏洞跟思維的嚴謹,就是當有高位需要輸出時一定要把位補起來,一般都是以1E18爲摸,所以一般都是有高位就輸出高位,接着把低位輸出,我說如果低位沒有18位整的呢?
拿100來說,高位是1,低位是99,這好,輸出來直接就是199,如果低位是9呢?輸出的就是19,低位的前導零沒有處理啊,有些代碼的正確只是建立在數據的不嚴謹啊。。
#include <iostream>
#include <cstdio>
#include <cstring>
#define Max(a,b) a>b?a:b
using namespace std;
__int64 mod=1000000000000000000;
int main (void)
{
int n,m,i,j,k,l;
__int64 dp[2][1111];
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(dp,0,sizeof(dp));
dp[0][0]=1;
if(m>n)m=n;
for(i=1;i<=m;i++)
for(j=i;j<=n;j++)
{
dp[1][j]=dp[1][j-i]+dp[1][j]+(dp[0][j-i]+dp[0][j])/mod; //高位
dp[0][j]=(dp[0][j-i]+dp[0][j])%mod; //低位
}
if(dp[1][n])
{
printf("%I64d",dp[1][n]);
printf("%018I64d\n",dp[0][n]); //補充前導零
}else
{
printf("%I64d\n",dp[0][n]); //這個不用補充前導零
}
}
return 0;
}