POJ3211 Washing Clothes

来源:互联网 发布:java成员变量 默认权限 编辑:程序博客网 时间:2024/06/01 07:12

传送门

这个题类似上一个题类似,发现各个颜色独立分别来求。

然后发现这个良心的题用时之和是一定的,差越小越好。

所以用dp[n][m]表示前n件差为m-sigma{k}的时候是否可行。

则找一个离sigma{k}最近的m使得dp[n][m]=true即可。

此时返回答案m/2。1A好评。

后记:另外也可以直接做dp[n][m]表示n件物品时间为m是否可行,这样找一个离sigma{k}最近的m即可。

代码:

//POJ 3211 #include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#define MAXK 100010#define MAXN 110#define p 10000007using namespace std;bool dp[MAXN][MAXK];//dp[n][m1][m2]=dp[m1-k[n]][m2]|dp[m1][m2-k[n]];//dp[n][m](m=m1-m2+M,M=sigma{k[i]})=dp[n-1][m-k[n]]|dp[n-1][m+k[n]].char ch[20];int s;struct node{int k;char id[20];}a[MAXN];bool cmp(const node &n1,const node &n2){return strcmp(n1.id,n2.id)>0;}int k[MAXN];int getdp(int n,int m){memset(dp[0],false,sizeof(dp[0]));dp[0][m]=true;for(int i=1;i<=n;i++)for(int j=0;j<=2*m;j++){dp[i][j]=false;if(j-k[i]>=0) dp[i][j]|=dp[i-1][j-k[i]];if(j+k[i]<=2*m) dp[i][j]|=dp[i-1][j+k[i]];}for(int i=0;i<=m;i++)if(dp[n][m+i]) return (m+i)/2;return 0;}int main(){int m,n;while(scanf("%d%d",&m,&n)!=EOF&&(n||m)){for(int i=1;i<=m;i++) scanf("%s",ch);for(int i=1;i<=n;i++){scanf("%d",&a[i].k);scanf("%s",a[i].id);}sort(a+1,a+n+1,cmp);int ans=0;for(int i=1;i<=n;i++){int cnt=0;while(i<=n&&strcmp(a[i].id,a[i+1].id)==0)k[++cnt]=a[i++].k;k[++cnt]=a[i].k;s=0;for(int j=1;j<=cnt;j++) s+=k[j];ans+=getdp(cnt,s);}printf("%d\n",ans);}return 0;}

原创粉丝点击