HDOJ 1864 最大报销额
今天做的两道DP和我以前做的不同,以前没试过换个变量来当作背包的容量,前面一道题奠定了这题的基础,这道题一看见的时候就知道用支票的个数来当容量,这道题有点题意不清,没看discuss的时候我也把题意理解错了,它说单项物品不超过600元其实是此类物品不超过600元,这道题也不能完全按照Robberies来做,这里有金额q的限制.
转移方程为d[i]=max(d[j])+p[i]; 1=<j<i;
代码:
#include<iostream> #include<cmath> using namespace std; double dp[35],p[35]; int main() { int n,flag,i,j,m; double q,sum,temp,d[100]; char ch; while( scanf("%lf%d",&q,&n)&&n){ j=1; for( i=1; i<=n; i++){ scanf("%d",&m); flag=1; sum=0; memset(d,0,sizeof(d)); while( m--){ scanf(" %c:%lf",&ch,&temp); d[ch-'A']+=temp; //是同类物品的累计 if( ch!='A'&&ch!='B'&&ch!='C'||d[ch-'A']>600){ flag=0; } sum+=temp; } if( sum<=1000&&flag) p[j++]=sum; } n=j-1; memset(dp,0,sizeof(dp)); double ret=0; for( i=1; i<=n; i++){ double mx=0.0; for( j=1; j<i; j++) if( dp[j]>mx&&dp[j]+p[i]<=q) mx=dp[j]; dp[i]=mx+p[i]; if( ret<dp[i]) ret=dp[i]; } printf("%.2lf\n",ret); } return 0; }
或者把最后的关键代码改成比较普通的0/1背包就比较好理解了。
for( i=1; i<=n; i++){ for( j=n; j>0; j--){ temp=dp[j-1]+p[i]; if( temp<=q&&temp>dp[j]) dp[j]=temp; } }
posted on 2012-07-19 21:04 java课程设计例子 阅读(228) 评论(0) 编辑 收藏 举报