1. 程式人生 > 其它 >2021.3.14 dp專練(1)

2021.3.14 dp專練(1)

題目:A.祖瑪遊戲

問題簡述:

  N個彈珠拍成一排, 編號1~N, i 號彈珠的顏色為Col[i]. 如果kzsn觸控到大於等於K顆連續的彈珠, 且這些彈珠的顏色相同, 那麼他會用摩法消除這段彈珠, 消除後前後兩端彈珠會自動碰在一起

  kzsn家中有很多彈珠, 他想知道在這N顆彈珠之間(也可以在開頭或結尾)插入最少最少彈珠, 才能使這N顆 +插入的彈珠全部消除

範圍:1<=N <=100, 2<=K<=5, 1<=Col[i]<=100

輸出:最少插入幾顆彈珠

  解:

#include<bits/stdc++.h>
using namespace
std; #define re register int const int inf = 0x3f3f3f3f; int n, K, Col[105], f[105][105][105]; void minn(int &x, int y) {if(y<x) x=y;} int dp(int x, int y, int k) { if(x>y) return 0; if(f[x][y][k] != inf) return f[x][y][k]; int p = y; while(Col[p] == Col[y] && p >= x) p --; p ++;
int delta; if(y+k+1-p >= K) delta = 0; else delta = K-(y+k+1-p); f[x][y][k] = dp(x, p-1, 0) + delta; for(re q = x;q < p;q ++) if(Col[q] == Col[y] && Col[q] != Col[q+1]) minn(f[x][y][k], dp(x, q, y+k+1-p) + dp(q+1, p-1, 0)); return f[x][y][k]; }
int main() { scanf("%d%d",&n,&K); memset(f, 0x3f, sizeof(f)); for(re i = 1;i <= n;i ++) scanf("%d",&Col[i]); printf("%d", dp(1, n, 0)); }

 分析 : 這題與"方塊消除"幾乎是雙倍經驗