CF思维联系–CodeForces - 225C. Barcode(二路动态规划)
ACM思維題訓練集合
Desciption
You’ve got an n?×?m pixel picture. Each pixel can be white or black. Your task is to change the colors of as few pixels as possible to obtain a barcode picture.
A picture is a barcode if the following conditions are fulfilled:
All pixels in each column are of the same color.
The width of each monochrome vertical line is at least x and at most y pixels. In other words, if we group all neighbouring columns of the pixels with equal color, the size of each group can not be less than x or greater than y.
Input
The first line contains four space-separated integers n, m, x and y (1?≤?n,?m,?x,?y?≤?1000; x?≤?y).
Then follow n lines, describing the original image. Each of these lines contains exactly m characters. Character “.” represents a white pixel and “#” represents a black pixel. The picture description doesn’t have any other characters besides “.” and “#”.
Output
In the first line print the minimum number of pixels to repaint. It is guaranteed that the answer exists.
Examples
input
6 5 1 2
##.#.
.###.
###…
#…#
.##.#
###…
output
11
input
2 5 1 1
…
output
5
Note
In the first test sample the picture after changing some colors can looks as follows:
.##…
.##…
.##…
.##…
.##…
.##…
In the second test sample the picture after changing some colors can looks as follows:
.#.#.
.#.#.
-------------------------****-------------------
先把每列修改的數量保存下來,都變成#的花費,和都變成‘ . ’的花費,這樣狀態就變成了第i列,就變成一個普通DP題。
為什么是二路動態規劃,是因為一開始的選擇有兩種,雖然一開始的顏色是有大有小的,但是基于動態規劃,當前最優解并不一定是全局最優,所以這一點我們把它們分成兩部分。
這道題思考起來沒有那沒有那么復雜,討論第i列染或不染(變成#或不變)但是無論染或不染都要至少染或不然連續的X以上,且不可超過Y列,那么就是說當換狀態時如果變成另一種狀態一定是從另一種狀態的連續的x到Y列變化而來,而不改變狀態時就是連續的一種狀態,累加當前狀態的消耗。進而得到狀態轉移方程
進而可得出代碼
#include <bits/stdc++.h> using namespace std; template <typename t> void read(t &x) {char ch = getchar();x = 0;int f = 1;while (ch < '0' || ch > '9')f = (ch == '-' ? -1 : f), ch = getchar();while (ch >= '0' && ch <= '9')x = x * 10 + ch - '0', ch = getchar();x *f; } #define wi(n) printf("%d ", n) #define wl(n) printf("%lld ", n) #define P puts(" ") typedef long long ll; #define MOD 1000000007 #define mp(a, b) make_pair(a, b) //---------------https://lunatic.blog.csdn.net/-------------------// const int maxn = 1005; const int INF = 0x3f3f3f3f; int cnt[maxn][2]; int dp[maxn][maxn][2]; int main() {int m, n, x, y;read(m),read(n),read(x),read(y);for (int i = 0; i < m; i++){for (int j = 0; j < n; j++){char x;scanf(" %c", &x);if (x == '#')cnt[j][1]++;elsecnt[j][0]++;}}memset(dp, 0x3f, sizeof(dp));for (int i = 0; i < n; i++){if (i == 0){for (int k = 0; k < 2; k++)dp[i][1][k] = cnt[i][k];continue;}for (int j = 1; j <= i+1&& j <= y; j++){if (j == 1){for (int k = x; k <= y; k++){dp[i][1][1] = min(dp[i - 1][k][0] + cnt[i][1], dp[i][1][1]);dp[i][1][0] = min(dp[i - 1][k][1] + cnt[i][0], dp[i][1][0]);}}else{dp[i][j][1] = dp[i - 1][j - 1][1] + cnt[i][1];dp[i][j][0] = dp[i - 1][j - 1][0] + cnt[i][0];}}}int ans = INF;for (int i = x; i <= y; i++){ans = min(dp[n - 1][i][0], min(dp[n - 1][i][1], ans));}wi(ans);P; }這個代碼我調了三個小時,寫出來之后!不知道為什么前邊用cin輸入這個題就過不了,而且每組樣例都能本地AC。尷尬,求解?
總結
以上是生活随笔為你收集整理的CF思维联系–CodeForces - 225C. Barcode(二路动态规划)的全部內容,希望文章能夠幫你解決所遇到的問題。