Timus 1167
简单DP,状态转移方程如下:
res[i][j]=min(res[i][j],res[k][j-1]+fact(k+1,i)) (1<=j<i && j<=m, 1<=i<=n, 1<=k<i);fact(i,j)表示从i到j的系数。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define MAX 1234567890 int res[501][501],fact[501][501],horse[501]; int min(int a,int b) { return a < b ? a : b; } int init(int n,int m) { int i,j,white,block; for(i=1;i<=n;i++) { white=block=0; for(j=i;j<=n;j++) { horse[j]==0 ? white++ : block++; fact[i][j]=white*block; } } return 0; } int work(int n,int m) { int i,j,k; for(i=0;i<=n;i++) res[i][1]=fact[1][i]; for(i=1;i<=n;i++) for(j=2;j<i && j<=m;j++) { res[i][j]=MAX; for(k=1;k<i;k++) res[i][j]=min(res[i][j],res[k][j-1]+fact[k+1][i]); } return res[n][m]; } int main() { int i,m,n; while(scanf("%d %d",&n,&m)!=EOF) { memset(res,0,sizeof(res)); memset(fact,0,sizeof(fact)); for(i=1;i<=n;i++) scanf("%d",&horse[i]); init(n,m); printf("%d\n",work(n,m)); } return 0; }