UVA 147 Dollars(完全背包)

题目链接:
UVA 147 Dollars
题意:
美元基础面额分为100美元,50美元,20美元,10美元,5美元,2美元,1美元以及50美分,20美分,10美分,5美分。1美元等于100美分。输入一个金额(保证是5美分的倍数),问由基础面额组成这个金额有多少种方法?
如:20美分:5美分*4;5美分*2+10美分;10美分*2;20美分。共4种。
分析:
完全背包。每种基础面额只要合法是无限取的。dp[i][j]表示前i种基础面额所能组成j的方法数

初始化:dp为0,但是dp[0][0]=1.

状态转移方程:

dp[i][j]=dp[i][j]+dp[i][j-data[i]];

其中data[i]代表第i种基础面额,因为输入是5美分的倍数,所以可以将基础面额和输入金额都除以5,也就是5美分对应1,10美分对应2。。。1美元对应20,。。。,100美元对应2000,一共11种基础面额。
注意:

  • ①:输入的精度问题。
total=(int)(n*100+0.5)/5;

而不是:

total=(int)(n*100)/5;
  • ②:要用long long。
//完全背包 176MS 0K
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX_VAL=6010;
int data[15]={0,1,2,4,10,20,40,100,200,400,1000,2000};

double n;
int total;
long long dp[MAX_VAL];

int main()
{
    freopen("Hin.txt","r",stdin);
    //freopen("Hout.txt","w",stdout);
    while(~scanf("%lf",&n)){
        if(n==0) break;
        total=(int)(n*100+0.5)/5;
        //printf("total=%d\n",total);
        memset(dp,0,sizeof(dp));
        dp[0]=1;
        for(int i=1;i<=11;i++){
            for(int j=data[i];j<=total;j++){
                dp[j]+=dp[j-data[i]];
                //printf("i=%d j=%d dp[j]=%d\n",i,j,dp[j]);
            }
        }
        printf("%6.2f%17lld\n",n,dp[total]);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值