【Codeforces Round #493 (Div. 2) B】Cutting
阿新 • • 發佈:2018-09-30
ifd main color ble -a 地方 name 次數 include
【鏈接】 我是鏈接,點我呀:)
【題意】
在這裏輸入題意
【題解】
顯然只有在前i個位置奇數偶數出現次數都相同的地方才能切。
(且不管前面怎麽切,這裏都能切的。
那麽就相當於有n個物品,每個物品的代價是|a[i]-a[i-1]|,然後價值是1.
問你不超過B的代價的最大價值是多少。
這就轉化成一個01背包模型了。
或者也可以這麽寫。
\(dp[i][j]表示前i個物品選擇(切)了j個的最小花費\)
然後dp[i][j]=min(dp[i-1][j-1]+cost[i],dp[i-1][j]);//分別表示切第i個與不切第i個。
然後從大到小遍歷一遍dp[n][i];輸出最大的使得dp[n][i]<=B的i就可以了
【代碼】
#include <bits/stdc++.h> using namespace std; const int N = 100; const int INF = 1e8; //dp[i][j] 前i個位置,cut了j次的最小花費 //dp[i][j] = min(dp[i-1][j-1]+cost[i],dp[i-1][j]); int dp[N+10][N+10],n,B; int pre[N+10][2],a[N+10],cost[N+10],cnt; int main() { #ifdef LOCAL_DEFINE freopen("rush.txt","r",stdin); #endif // LOCAL_DEFINE ios::sync_with_stdio(0),cin.tie(0); cin >> n >> B; for (int i = 1;i <= n;i++) cin >> a[i]; for (int i = 1;i <= n;i++){ for (int j = 0;j < 2;j++) pre[i][j] = pre[i-1][j]; pre[i][a[i]&1]++; } for (int i = 1;i <= n-1;i++) if (pre[i][0]==pre[i][1]){ cost[++cnt] = abs(a[i+1]-a[i]); } n = cnt; for (int i = 0;i <= N;i++) for (int j = 0;j <= N;j++) dp[i][j] = INF; dp[0][0] = 0; for (int i = 1;i <= n;i++) for (int j = 0;j <= i;j++){ dp[i][j] = dp[i-1][j];//no cut i if (j>0){ dp[i][j] = min(dp[i][j],dp[i-1][j-1]+cost[i]);//cut i } } for (int j = n;j >= 0;j--){ if (dp[n][j]<=B){ cout<<j<<endl; return 0; } } return 0; }
【Codeforces Round #493 (Div. 2) B】Cutting