Dollar Dayz
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 7708 | Accepted: 2879 |
Description
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$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
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~K的商品数量不限,计算能买到总价为N的种类数。
思路:如果用朴素dp,会超时,观察得a[i][j]=a[i][j-1]+a[i-j][j-1]+a[i-2j][j-1]+a[i-3j][j-1]…+a[0][j-1],即分为购买i和不购买i。
这样就可以简化得到:a[i][j]=a[i][j-1]+a[i-j][j],这样一来就简化了一层循环,又因为最终得到的数字可能很大,所以用上一些技巧,把结果分成两部分。
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int n,k;
long long a[1100][110],b[1100][110],inf=1;
void solve()
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(int i=0;i<18;i++)inf*=10;
for(int i=0;i<=k;i++) a[0][i]=1;
for(int i=1;i<=k;i++)
{
for(int j=1;j<=n;j++)
{
if(j-i<0) //买到总价为j小于i则不可能买i
{
a[j][i]=a[j][i-1];
b[j][i]=b[j][i-1];
continue;
}
b[j][i]=b[j][i-1]+b[j-i][i]+(a[j][i-1]+a[j-i][i])/inf;
a[j][i]=(a[j][i-1]+a[j-i][i])%inf;
}
}
if(b[n][k]!=0)printf("%I64d",b[n][k]); //b为高位
printf("%I64d\n",a[n][k]); //a为低位
}
int main()
{
cin>>n>>k;
solve();
}