poj 3211 Washing Clothes
分析:因为要洗完所有同种颜色的才能洗下一种颜色,所以先按颜色排序,对每种颜色做一次01背包。取两个最少时间的最大值,累加
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<map> 5 #include<string> 6 #include<iostream> 7 #define N 1100 8 using namespace std; 9 int dp[N][N],w[N][N],cnt[N],sum[N]; 10 int main(){ 11 int m,n; 12 while(cin>>m>>n){ 13 if(m==0&&n==0) 14 return 0; 15 map<string,int>q; 16 memset(dp,0,sizeof(dp)); 17 memset(cnt,0,sizeof(cnt)); 18 memset(sum,0,sizeof(sum)); 19 for(int i=1;i<=m;i++){ 20 string s; 21 cin>>s; 22 q[s]=i; 23 } 24 for(int i=1;i<=n;i++){ 25 string s; 26 int k; 27 cin>>k>>s; 28 w[q[s]][++cnt[q[s]]]=k; 29 sum[q[s]]+=k; 30 } 31 int ans=0; 32 for(int i=1;i<=m;i++){ 33 for(int j=1;j<=cnt[i];j++){ 34 for(int k=sum[i]/2;k>=w[i][j];k--) 35 dp[i][k]=max(dp[i][k],dp[i][k-w[i][j]]+w[i][j]); 36 37 } 38 ans+=max(dp[i][sum[i]/2],sum[i]-dp[i][sum[i]/2]); 39 } 40 printf("%d\n",ans); 41 42 } 43 return 0; 44 }