1651 Multiplication Puzzle
問題概要
n枚の数字の書かれたカードが一列に並んでいる。
これを使って以下のようなゲームをする。
- 両端以外のカードを一枚選び、そのカードと、その両隣のカードの数字3つを掛けた数をスコアに足す
- そのカードを取り除く
- この操作を残りのカードが2枚になるまで繰り返す
このとき、スコアの最小値を求めよ。
解法
dp[i][j]をi枚目からj枚目までのカードのうち、両端を残して間を全て取り除くのに必要な最小のスコアとすると、
dp[i][j]=min{dp[i][k]+dp[k][j]+(i,k,jの数字の積)}となる。
この漸化式を使うことでO(n^3)のDPができる。
ソースコード
int n,c[100]; int dp[100][100]; int main() { scanf("%d",&n); rep(i,n)scanf("%d",c+i); rep(i,n)rep(j,n)dp[i][j]=inf; rep(i,n-1)dp[i][i+1]=0; for(int len=3;len<=n;len++)rep(l,n-len+1) { int r=l+len-1; for(int m=l+1;m<r;m++)dp[l][r]=min(dp[l][r],dp[l][m]+dp[m][r]+c[l]*c[m]*c[r]); } printf("%d\n",dp[0][n-1]); return 0; }