题解:AT_pakencamp_2019_day3_d パ研軍旗
题意过于简洁不必复述了。
显而易见,为了使原矩阵成为一个军旗,每一列到最后的时候都应当处于全红,全蓝或全白这三种状态之一,其中全黑是不可以的。那就直接分类讨论每一列的三种情况。
例如:我们存储每一列改为全红,全蓝或全白三种状态的最小代价分别为 \(a_{1,1},a_{2,1},a_{3,1}\),那么下一列改为这三种状态之一的代价就是前一列与它颜色不同的两种中的最小代价与自己这一列全部改为该颜色的最小代价之和。
再通俗些:\(a_{2,1}\) 就应该是第二列改为全红的代价加上 \(a_{2,1},a_{3,1}\) 的较小值。
由此思路就已经出来了。上代码:
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
int n,a[1145][4],dp[1145][4],ans=1000000005;
char c;
int main(){
ios;cin>>n;
for(int j=1;j<=5;j++){
for(int i=1;i<=n;i++){
cin>>c;
if(c=='R'){
a[i][1]++,a[i][2]++;
}
if(c=='B'){
a[i][1]++,a[i][3]++;
}
if(c=='W'){
a[i][2]++,a[i][3]++;
}
if(c=='#'){
a[i][1]++,a[i][2]++,a[i][3]++;
}
// 存储这一列换几次可以成为清一色的某种颜色
// 黑色的不能存在所以每种都要加
}
}
// 输入完毕后a[i][]对应的就是该颜色的数量
for(int i=1;i<=n;i++){
for(int j=1;j<=3;j++){
dp[i][j]=1000000005;
for(int c=1;c<=3;c++){
if(j!=c){
if(dp[i][j]>dp[i-1][c]+a[i][j])
dp[i][j]=dp[i-1][c]+a[i][j];
}
}
}
}
// 最后一次循环出结果
for(int j=1;j<=3;j++){
if(ans>dp[n][j])ans=dp[n][j];
}
cout<<ans<<'\n';
return 0;
}
感谢阅读!
本文来自博客园,作者:Circle_Table,转载请注明原文链接:https://www.cnblogs.com/Circle-Table/articles/19177398

浙公网安备 33010602011771号