rt,代码如下,感觉和题解思路差距比较大,而且我是从前往后 DP 的,因此求该份代码是否为正解,如果不是,是否可以 hack。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,a[3001],b[3001],c[3001][3001],x[3001][3001],s;//设c[i][j]为前i个格子,可以清除j个格子的最大得分
bool y[3001][3001];
inline void dfs(int i,int j,int k){
if(i!=0&&x[i][j]!=-1){
if(y[i][j]){
dfs(i-1,x[i][j],k+1);
}
else{
dfs(i-1,x[i][j],k);
}
}
else{
if(y[i][j]){
cout<<k+1<<'\n';
}
else{
cout<<k<<'\n';
}
}
if(y[i][j]){
cout<<i<<' ';
}
}
signed main(){
cin.tie(nullptr)->sync_with_stdio(0);
memset(x,-1,sizeof(x));
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
cin>>b[i];
}
for(int i=0;i<=n;i++){
for(int j=0;j<=n;j++){
c[i][j]=LONG_LONG_MIN;
}
}
for(int i=1;i<=n;i++){
c[i][0]=a[i];
c[i][1]=0;
y[i][0]=y[i][1]=1;
}
for(int i=1;i<=n;i++){
for(int j=0;j<=s-b[i]+1;j++){//清除所有格子
if(c[i][j]<0){
c[i][j]=0;
x[i][j]=s;
y[i][j]=1;
}
}
s=0;
for(int j=0;j<=i-b[i]-1;j++){//选
if(c[i-1][j+b[i]]!=LONG_LONG_MIN){
if(c[i][j]<c[i-1][j+b[i]]+a[i]){
c[i][j]=c[i-1][j+b[i]]+a[i];
x[i][j]=j+b[i];
y[i][j]=1;
}
}
}
for(int j=0;j<=n;j++){//不选
if(c[i][j]<c[i-1][j]){
c[i][j]=c[i-1][j];
x[i][j]=j;
y[i][j]=0;
}
if(c[i][j]!=LONG_LONG_MIN){
s=j;
}
}
}
s=0;
for(int i=0;i<=n;i++){
if(c[n][i]>c[n][s]){
s=i;
}
}
if(c[n][s]==0){
cout<<"0\n\n";
}
else{
dfs(n,s,0);
}
cout<<'\n'<<c[n][s];
return 0;
}