您的位置:首页 > 其它

UVA 147 Dollars(完全背包)

2016-04-03 21:52 525 查看
题目链接:

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  uva dp 完全背包