topic
Given an array a(1<=ai<=3e3) of length n(n<=3e3),
You can do the following any number of times:
1. Select a continuous sub-array of a and delete it
For x=1,2,...,m, answer the questions separately:
1. Find the minimum number of deletions so that the sum of the remaining undeleted elements is equal to x, and output the minimum number of deletions
2. If not possible, output -1
In particular, empty array elements and , are considered to be 0
source of ideas
Teacher Cai
answer
dp[i][j][k] means: when considering the first i elements, the sum of the elements that are not currently deleted is j,
When the last element (i-th element) is deleted (0/1), the corresponding minimum number of deletions is dp[i][j][k],
If dp[i][j][k] is INF, it means that this state is illegal
Transfer is similar to a backpack, enumerating whether the last element is deleted or not, and whether the last element is deleted or not,
The current 01 is transferred from the previous 01, four cases
the code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3e3+5,INF=0x3f3f3f3f;
int n,m,dp[N][N][2],a[N];
int main(){
cin>>n>>m;
for(int i=1;i<=n;++i){
cin>>a[i];
}
memset(dp,INF,sizeof dp);
dp[0][0][0]=0;
dp[0][0][1]=1;
for(int i=1;i<=n;++i){
for(int j=0;j<=m;++j){
dp[i][j][1]=min(dp[i-1][j][1],dp[i-1][j][0]+1);
if(j>=a[i])dp[i][j][0]=min(dp[i-1][j-a[i]][1],dp[i-1][j-a[i]][0]);
}
}
for(int i=1;i<=m;++i){
int ans=min(dp[n][i][0],dp[n][i][1]);
printf("%d\n",ans==INF?-1:ans);
}
return 0;
}