PKU演習問メモ(6/13)
何か土日疲れが出てて全然問題解けなかったなあ。
最近全然実力向上してないし、こんなんじゃますます停滞するよorz
No. | 問題名 | 問題の種類および解法 | 難易度 |
---|---|---|---|
2978 | Colored stones | ビットDP | ★★☆☆☆ |
2978 Colored stones
問題概要
m個の石の色が一列に並んでおり、それぞれの色は1...kのうちいずれかである。
m,k,各石の色が与えられたとき、列から石を取り除いて「どの同じ色の二つの石の間にも、他の色の石が入っていない」状態にしたい。
取り除く石の個数の最小値を求めよ。
解法
原文の問題文では、"What is the minimum number of stones you must remove so that no two stones of one color are separated by a stone of a different color"
なのだけど、これって二つの同色の石の間に違う色の石"1個"が挟まれないように、って読めちゃう気が……
それで3回ほどWA出した。
解法はビットDPによる。すなわち、[i個の石までの][その中に各石が含まれてるかのビット表現][右端の石の色]の最適解のテーブルを作って更新していく。
ソースコード
int m,k,color[100]; int dp[101][1<<6][6]; int main() { while(cin>>m>>k,m) { rep(i,m)cin>>color[i]; rep(i,m+1)rep(j,1<<k+1)fill_n(dp[i][j],k+1,inf); dp[0][0][0]=0; for(int i=1;i<=m;i++)rep(bit,1<<k+1)rep(j,k+1) { //not skip if(color[i-1]==j||(bit&1<<color[i-1])==0) dp[i][bit|1<<color[i-1]][color[i-1]]= min(dp[i][bit|1<<color[i-1]][color[i-1]],dp[i-1][bit][j]); //skip dp[i][bit][j]=min(dp[i][bit][j],dp[i-1][bit][j]+1); } int ans=m; rep(bit,1<<k+1)rep(i,k+1)ans=min(dp[m][bit][i],ans); cout<<ans<<endl; } return 0; }