专栏文章
题解:P2135 方块消除
P2135题解参与者 3已保存评论 2
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @miqj4vjz
- 此快照首次捕获于
- 2025/12/04 05:39 3 个月前
- 此快照最后确认于
- 2025/12/04 05:39 3 个月前
题解区没看到有这做法的,就发一篇题解吧。
表示 到 全部消除所获得的最大收益,考虑如何处理一个区间 。
首先区间最左(或最右)的颜色是可以放到组后消除并不影响答案的,所以我们钦定最后消除这个区间左端点,对于每个区间做一个背包, 表示最后一次消除的颜色中最后面的位置为 且此颜色数量为 的最大收益(不包括此颜色),最后取 即为 。
代码。
CPP#include<bits/stdc++.h>
using namespace std;
const int N = 60;
int n,co;
int f[N][N],g[N][1001];
int c[N],a[N];
inline void get(int l,int r)
{
int s=0,p=c[l],res=0;
g[l][a[l]]=0,s=a[l];
res=a[l]*a[l]+f[l+1][r];
for(int i=l+1;i<=r;i++)
{
if(c[i]!=p)continue;
s+=a[i];
for(int j=l;j<i-1;j++)
{
if(c[j]!=p)continue;
for(int e=a[i];e<=s;e++)
g[i][e]=max(g[i][e],g[j][e-a[i]]+f[j+1][i-1]),res=max(res,g[i][e]+e*e+f[i+1][r]);
}
}
s=a[l];
for(int i=l+1;i<=r;i++)
{
if(c[i]!=p)continue;
s+=a[i];
for(int j=l;j<i-1;j++)
{
if(c[j]!=p)continue;
for(int e=a[i];e<=s;e++)
g[i][e]=-1e9;
}
}
f[l][r]=res;
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
memset(g,0xcf,sizeof g);
for(int i=1;i<=n;i++)cin>>c[i];
for(int i=1;i<=n;i++)cin>>a[i],f[i][i]=a[i]*a[i];
for(int len=2;len<=n;len++)
for(int l=1;l+len-1<=n;l++)
get(l,l+len-1);
cout<<f[1][n];
}
相关推荐
评论
共 2 条评论,欢迎与作者交流。
正在加载评论...