hdu 1864 最大报销额(01背包d )

来源:互联网 发布:淘宝网店铺怎么开 编辑:程序博客网 时间:2024/06/06 01:35

http://acm.hdu.edu.cn/showproblem.php?pid=1864

这里有让人犯迷糊的地方,可能是题意不清楚。当满足下面条件之一的,这张发票就不能报销,相当于作废:

1.一张发票上有除了 'A' 'B' C"之外还有别的类型的消费

2.这张发票的总总消费大于1000

3.单项物品的价值超过600


这样就变成了01背包问题。即某张发票被报销和不被报销两种情况。

还有就是给定的总额和发票的消费总额都是两位小数,可以先给他们同时扩大100倍,最后输出的时候再缩小100倍。


#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int maxn = 3000010;int dp[maxn];int chk(char ch){if(ch == 'A' || ch == 'B' || ch == 'C')return 1;return 0;}int main(){double Q;int n,m,v;int a[40];while(~scanf("%lf %d",&Q,&n)){if(n == 0) break;v = Q*100;//指定报销额扩大100倍for(int i = 1; i <= n; i++){scanf("%d",&m);double A = 0,B = 0,C = 0,x,s = 0;int f = 1;char str;while(m--){scanf(" %c:%lf",&str,&x);if(chk(str) == 0) f = 0;if(str == 'A') A += x;if(str == 'B') B += x;if(str == 'C') C += x;s += x;}if(A > 600 || B > 600 || C > 600 || s > 1000 || f == 0)a[i] = 0;//该发票不符合要求,置为0.else a[i] = s*100;//否则发票的总价值也扩大100倍}memset(dp,0,sizeof(dp));dp[0] = 1;//初始化。0肯定能达到int ans = 0;for(int i = 1; i <= n; i++){for(int j = v; j >= a[i]; j--){if(dp[j-a[i]]){dp[j] = 1;ans = max(ans,j);}}}printf("%.2lf\n",ans/100.0);//最后还原}return 0;}


0 0
原创粉丝点击