题目地址:Ural 1167
感觉这题的思路类似于背包的做法。。
先预处理出来每个马与之前所有的马的0的数量和1的数量,用数组a[0][i]和a[1][i]来表示。
然后再用数组dp[i][j]来表示当前第i个马槽最右端为第j个马时的最小值。
dp的时候先枚举马槽,再用n*n枚举当前的马槽要选用的马的区间。这样总时间复杂度是O(n*n*k)。
代码如下:
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <queue> #include <map> #include <set> #include <algorithm> using namespace std; const int INF=0x3f3f3f3f; #define LL long long int a[3][600], dp[600][600], c[600]; int main() { int n, k, i, j, x, h; c[0]=0; scanf("%d%d",&n,&k); for(i=1; i<=n; i++) { scanf("%d",&c[i]); } a[0][0]=0; a[1][0]=0; for(i=1; i<=n; i++) { a[0][i]=c[i]==0?a[0][i-1]+1:a[0][i-1]; a[1][i]=c[i]==1?a[1][i-1]+1:a[1][i-1]; } memset(dp,INF,sizeof(dp)); dp[0][0]=0; for(i=1;i<=k;i++) { for(j=1;j<=n;j++) { for(h=0;h<j;h++) { dp[i][j]=min(dp[i][j],dp[i-1][h]+(a[0][j]-a[0][h])*(a[1][j]-a[1][h])); } } } printf("%d\n",dp[k][n]); return 0; }
时间: 2024-11-05 05:17:38