码迷,mamicode.com
首页 > 其他好文 > 详细

Dollar Dayz 【完全背包+高精度】

时间:2017-03-27 23:04:19      阅读:272      评论:0      收藏:0      [点我收藏+]

标签:++i   disco   highlight   cpp   cstring   include   string   fine   uri   

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

 
题意:有n元钱,商品的价格在1~k元(每种价格的商品数量无限),用n元去买这些商品,最多有多少种选择?
 
题解:
根据完全背包思想,第一个循环表示商品价值(i),第二个循环表示我的本钱(j)。
得出方程:dp[j] = dp[j] + dp[j-i]
  • dp[j]表示当商品价格最大为 i 时,我用 j 元买这些商品的选择数。
  • dp[j-i]就是根据背包问题的二进制思想来计数当有 i (当前 i 和之前算过的 i)的倍数元时的商品选择数。
 
当然,题目肯定不会那么简单,n范围是1000,k范围是100,会超出long long,所以我们可以把dp拆成两个数组,一个存储高位数,一个存低位数,最后拼接输出。
 
核心部分:
  1. a[j]=a[j]+a[j-i]+(b[j]+b[j-i])/INF;
  2. b[j]=(b[j]+b[j-i])%INF;
我们用a来存高位,用b来存低位(19位数之前),也就是说在19位数之前,a一直都是0,当超过19位数时,a才有能值。
 
也许这部分a[j]=a[j]+a[j-i]+(b[j]+b[j-i])/INF有些难理解,它和状态方程不太一样。其实并不是把超出部分直接赋予a即可,我们还不能忘记要记录超出部分的状态。
 
如下:
#include<cstdio>  
#include<cstring>  
#define ll __int64  
ll INF=1000000000000000000;  
ll a[1010];//高位   
ll b[1010];//低位   
int main()  
{  
    int n,k,i,j;  
    while(scanf("%d%d",&n,&k)!=EOF)  
    {  
        memset(a,0,sizeof(a));  
        memset(b,0,sizeof(b));  
        b[0]=1;  
        for(i=1;i<=k;++i)  
        {  
            for(j=i;j<=n;++j)  
            {  
                a[j]=a[j]+a[j-i]+(b[j]+b[j-i])/INF;  
                b[j]=(b[j]+b[j-i])%INF;  
            }  
        }  
        if(a[n]==0)  
            printf("%I64d\n",b[n]);  
        else  
            printf("%I64d%018I64d\n",a[n],b[n]);  
    }  
    return 0;  
}   

  

 
 

Dollar Dayz 【完全背包+高精度】

标签:++i   disco   highlight   cpp   cstring   include   string   fine   uri   

原文地址:http://www.cnblogs.com/redscarf/p/6629294.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!