一道应该不是很难的动规题,求找错,WA得受不了了
http://acm.neu.题目大意:n个数(只为0,1,2),按顺序分成m组,使得所有组的积加起来最大。
思路应该是动规,用f[i,j]表示前i个数分成j组的最大值,枚举第j组从k到i,则f[i,j]=Max(f[k-1,j-1]+(k--i的乘积)) (k>=j),下面是我的程序,wa到暴
程序代码:
#include <stdio.h> #include <stdlib.h> long long f[55][55],tpow[55],tmp; int zero[55],one[55],two[55],n,m,a[55],i,j,k; int main() { tpow[0]=1; for (i=1; i<=50; i++) tpow[i]=tpow[i-1]*2; //预处理出2的阶乘和,这样求k--i个数的乘积可以直接由其中2的个数得到 while (scanf("%d%d",&n,&m),n!=0) { zero[0]=0; one[0]=0; two[0]=0; for (i=1; i<=n; i++) { scanf("%d",a+i); zero[i]=zero[i-1]; one[i]=one[i-1]; two[i]=two[i-1]; if (a[i]==0) zero[i]++; else if (a[i]==1) one[i]++; else two[i]++; } memset(f,0,sizeof(f)); for (i=1; i<=n; i++) { if (zero[i]==0) f[i][1]=tpow[two[i]]; else f[i][1]=0; //先直接求出f[i][1] for (j=2; j<=m; j++) { if (j>i) break; for (k=j; k<=i; k++) //对f[i][j]开始枚举动规,由于剩下k-1个数分成j-1组,克制k>=j { if (zero[k-1]==zero[i]) tmp=tpow[two[i]-two[k-1]]; else tmp=0; if (f[i][j]<f[k-1][j-1]+tmp) f[i][j]=f[k-1][j-1]+tmp; } } } printf("%lld\n",f[n][m]); } return 0; }