luogu4267 TamingtheHerd (dp)

设f[i][j]为让前i天发生j次暴动需要改变的最少的值

则f[i][j]=min{f[k][j-1]+(x[k+1]!=0)+(x[k+2]!=1)+...+(x[i]!=(i-k-1))}

$O(n^3)$直接做就好了

 1 #include<bits/stdc++.h>
 2 #define pa pair<int,int>
 3 #define ll long long
 4 using namespace std;
 5 const int maxn=105;
 6 
 7 ll rd(){
 8     ll x=0;char c=getchar();int neg=1;
 9     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
10     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
11     return x*neg;
12 }
13 
14 int N,num[maxn],f[maxn][maxn],dif[maxn][maxn];
15 
16 int main(){
17     int i,j,k;
18     N=rd();for(i=1;i<=N;i++) num[i]=rd();
19     for(i=1;i<=N;i++){
20         for(j=i;j<=N;j++) dif[i][j]=dif[i][j-1]+(num[j]!=j-i);
21     }
22     memset(f,127,sizeof(f));f[0][0]=0;
23     for(i=1;i<=N;i++){
24         for(j=1;j<=i;j++){
25             for(k=0;k<i;k++){
26                 f[i][j]=min(f[i][j],f[k][j-1]+dif[k+1][i]);
27             }
28         }
29     }for(i=1;i<=N;i++) printf("%d\n",f[N][i]);
30     return 0;
31 }

 

posted @ 2018-09-11 16:46  Ressed  阅读(188)  评论(0编辑  收藏  举报