1 /************************************* 2 3 题目: Washing Clothes(poj 3211) 4 链接: http://poj.org/problem?id=3211 5 算法: 分组背包 6 由于题目有字符串不好处理,用map 7 函数来处理后做法和一般分组背包 8 一样了。然后对没中颜色做01背包 9 就可以了。 10 11 **************************************/ 12 13 14 #include<iostream> 15 #include<map> 16 #include<cstdio> 17 #include<cstring> 18 using namespace std; 19 20 map<string,int>g1,g2; ///g1记录每个颜色出现的循序, 21 ///g2记录每个颜色出现的次数。 22 23 int a[15][150]; 24 char s[150][15]; 25 int dp[10000]; 26 27 int main() 28 { 29 int n,m,i,j,k; 30 while (~scanf("%d%d",&n,&m)) 31 { 32 if (n==0&&m==0) return 0; 33 g1.clear(); 34 g2.clear(); 35 for (i=0;i<n;i++) 36 { 37 scanf("%s",&s[i]); 38 g1[s[i]]=i; 39 } 40 while (m--) 41 { 42 char s[15]; 43 int x; 44 scanf("%d %s",&x,&s); 45 a[g1[s]][g2[s]++]=x; 46 } 47 int ans=0; 48 49 /// 分组背包 50 for (i=0;i<n;i++) 51 { 52 memset(dp,0,sizeof(dp)); 53 int cut=0; 54 for (j=0;j<g2[s[i]];j++) cut+=a[i][j]; 55 for (j=0;j<g2[s[i]];j++) ///01背包 56 { 57 for (k=cut/2;k>=a[i][j];k--) 58 dp[k]=max(dp[k],dp[k-a[i][j]]+a[i][j]); 59 } 60 ans+=cut-dp[cut/2]; 61 }
62 cout<<ans<<endl; 63 } 64 }