BZOJ5196: [Usaco2018 Feb]Taming the Herd(DP暴力)
阿新 • • 發佈:2018-11-14
5196: [Usaco2018 Feb]Taming the Herd
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 78 Solved: 71
[Submit][Status][Discuss]
Description
一大清早,Farmer John就被木材破裂的聲音吵醒了。是這些奶牛們乾的,她們又逃出牛棚了!Farmer John已經厭 煩了奶牛在清晨出逃,他覺得受夠了:是時候採取強硬措施了。他在牛棚的牆上釘了一個計數器,追蹤從上次出逃 開始經過的天數。所以如果某一天早上發生了出逃事件,這一天的計數器就為0;如果最近的出逃是3天前,計數器 讀數就為3。Farmer John一絲不苟地記錄了每一天計數器的讀數。年末到了,Farmer John準備做一些統計。他說 ,你們這些奶牛會付出代價的!然而他的某些記錄看上去不太對勁……Farmer John想要知道從他開始記錄以來發 生過多少次出逃。但是,他懷疑這些奶牛篡改了它的記錄,現在他所確定的只有他是從發生出逃的某一天開始記錄 的。請幫助他求出,對於每個從他開始記錄以來可能發生的出逃次數,他被篡改了的記錄條數的最小值。Input
Output
輸出包含N個整數,每行一個。 第i個整數為所有發生i次出逃的事件序列中,與該事件序列不一致的記錄條目條數的最小值。Sample Input
61 1 2 0 0 1
Sample Output
42
1
2
3
4
如果只發生1次出逃,則正確的記錄應該為0 1 2 3 4 5,有4處與給定的記錄不同。
如果發生2次出逃,則正確的記錄可能為0 1 2 3 0 1,有2處與給定的記錄不同。
在這個例子中,出逃發生在第一天和第五天。
如果發生3次出逃,則正確的記錄可能為0 1 2 0 0 1,僅有1處與給定的記錄不符。
在這個例子中,出逃發生在第一天、第四天和第五天。
以此類推。
思路:dp[i][j][k]表示第i個數以k結尾的,且用了j個0的最小修改次數,然後可以得到O(N^3)的 方程。
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; const int maxn=110; const int inf=0x3f3f3f3f; int N,a[maxn],dp[maxn][maxn][maxn],ans[maxn]; int main(){ scanf("%d",&N); rep(i,1,N) scanf("%d",&a[i]); memset(dp,0x3f,sizeof(dp)); memset(ans,0x3f,sizeof(ans)); dp[1][1][0]=(a[1]!=0); rep(i,2,N){ rep(j,1,i){ rep(k,0,i-j) dp[i][j][0]=min(dp[i][j][0],dp[i-1][j-1][k]+(a[i]!=0)); rep(k,1,i-j) dp[i][j][k]=min(dp[i][j][k],dp[i-1][j][k-1]+(a[i]!=k)); } } rep(i,1,N) rep(j,0,N) ans[i]=min(ans[i],dp[N][i][j]); rep(i,1,N) printf("%d\n",ans[i]); return 0; }