原題連結
題解
程式碼量小的離譜,思維難度大的離譜
對於兩個原本不相鄰的同色區域塊,歷經千辛萬苦碰面的場景,我們可以描述成右邊的區域塊為左邊的區域塊消除的時候增添了長度
設 \(dp[i][j][suf]\) 代表消除區域 \([i,j]\) 同時該區域的 \(j\) 增添了長度 \(suf\)
但是合併消除不一定是最優的,因為可能破壞中間的可能長度更長的合併塊
所以初始化是不合並的情況
然後尋找所有可能合併的區域塊,完成上述操作
tai chou xiang le!!!
suf是向下傳遞的
code
#include<bits/stdc++.h>
using namespace std;
int dp[55][55][1005]={0},a[55]={0},num[55]={0};
int ss(int l,int r,int suf)
{
if(l>r) return 0;
if(dp[l][r][suf]) return dp[l][r][suf];
if(l==r) return (dp[l][r][suf]=(num[r]+suf)*(num[r]+suf));
dp[l][r][suf]=ss(l,r-1,0)+(num[r]+suf)*(num[r]+suf);
for(int i=l;i<r;i++) if(a[i]==a[r]) dp[l][r][suf]=max(dp[l][r][suf],ss(l,i,suf+num[r])+ss(i+1,r-1,0));//中間的消除
return dp[l][r][suf];
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>num[i];
cout<<ss(1,n,0);
return 0;
}