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

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

来源: https://vjudge.net/problem/description/9920

题意:有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;
}

  

时间: 2024-10-07 18:46:19

Dollar Dayz 【完全背包+高精度】的相关文章

POJ 3181 Dollar Dayz(完全背包+简单高精度加法)

POJ 3181 Dollar Dayz(完全背包+简单高精度加法) http://poj.org/problem?id=3181 题意: 给你K种硬币,每种硬币分别是1美元,2美元-K美元且可以无限使用,问你用上面K种硬币构成n美元的话有多少种方法? 分析: 本题是一道明显的完全背包问题, 不过本题还可以换一种方法来看: 整数n由前K个自然数构造, 一共有多少种方法? (虽然本题要用到高精度加法, 但是很简单, 不要被吓到哦) 首先是DP部分: 令dp[i][j]==x 表示由前i种硬币构成j

POJ 3181 Dollar Dayz ( 完全背包 &amp;&amp; 大数高精度 )

题意 : 给出目标金额 N ,问你用面额 1~K 拼成 N 的方案有多少种 分析 : 完全背包的裸题,完全背包在 DP 的过程中实际就是列举不同的装填方案数来获取最值的 故状态转移方程为 dp[i] += dp[j-w[i]] 但是这题怎么可能那么简单呢! N 和 K 的上限导致答案过大,需要使用高精度加法来完成 所以无耻的用 JAVA 来搞定了 import java.io.*; import java.lang.reflect.Array; import java.util.*; impor

POJ3181 Dollar Dayz 【母函数】+【高精度】

Dollar Dayz Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4204   Accepted: 1635 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 sell

Dollar Dayz (大数dp fuck!不是多组数据!!)

Dollar Dayz Time Limit: 1000ms Memory Limit: 65536KB 64-bit integer IO format: %lld      Java class name: Main Prev Submit Status Statistics Discuss Next Farmer John goes to Dollar Days at The Cow Store and discovers an unlimited number of tools on s

poj3181 Dollar Dayz (DP+大数)

Dollar Dayz Crawling in process... Crawling failed Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 3181 Appoint description: System Crawler (2016-05-27) Description Farmer John goes to Dollar Da

POJ 3181 Dollar Dayz &amp;&amp; Uva 147 Dollars(完全背包)

首先是 Uva 147:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=83 细心看完这题后发现还是完全背包,只不过需要对浮点数处理一下.即把所有硬币的面值都乘以100,化为整数,对输入的数据也作同样的处理,然后就是套完全背包的模板了,在输出时还要用格式和精度来卡一卡你……一开始我没想到用printf可以的,于是百度了cout的输出格式控制,

(完全背包 大数)Dollar Dayz (POJ 3181)

http://poj.org/problem?id=3181 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

POJ 3181 Dollar Dayz 【完全背包】

题意: 给出两个数,n,m,问m以内的整数有多少种组成n的方法完全背包+大数划分 思路: dp[i][j] := 用i种价格配出金额j的方案数. 那么dp[i][0] = 1,使用任何价格配出金额0的方案个数都是1(什么都不用). 递推关系式: 实际上是完全背包问题,只是状态转移方程形式有所不同,不过状态转移的方向是完全相同的. dp[i][j] = dp[i – 1][j] + dp[i – 1][j – i] + dp[i – 1][j – 2 * i] + - + dp[i – 1][0]

POJ Dollar Dayz 美元假日(完全背包,常规+大数)

题意:给出整数n和k,n代表拥有的钱数量,k代表有k种工具,其价钱分别为1~k.求n元能有多少种购买的方案. 思路:k最大有100,数量过大,要用大数.其他的基本和完全背包一样. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int B=1005, N=150; 7 int