AtCoder Beginner Contest 275 F. Erase Subarrays(线性dp)

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;
}

Guess you like

Origin blog.csdn.net/Code92007/article/details/129906240