NC19158 失衡天平(背包dp)

复健牛客每日一题系列

这题的dp感觉很浓,因为数据范围给的很像dp

刚开始我被能多次操作困惑了,以为是什么巧妙的贪心

但是其实多次能拿,一次也能拿,我们可以通过放的位置控制在m之内

因此这题是一道背包dp,因为每个物品都有三种选择,左边右边或者不放,而第二维状态可以表示为两边的差值

这题会产生负的,因此我们要对区间进行平移

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int N=1e6+10;
const int mod=1e9+7;
int a[N],f[110][20020];
int main(){
    ios::sync_with_stdio(false);
    int n,m;
    cin>>n>>m;
    int i,j;
    memset(f,-0x3f,sizeof f);
    f[0][10000]=0;
    for(i=1;i<=n;i++)
        cin>>a[i];
    int ans=0;
    for(i=1;i<=n;i++){
        for(j=0;j<=20000;j++){
            f[i][j]=max(f[i][j],f[i-1][j]);
            if(j+a[i]<=20000){
                f[i][j]=max(f[i][j],f[i-1][j+a[i]]+a[i]);
            }
            if(j-a[i]>=0){
                f[i][j]=max(f[i][j],f[i-1][j-a[i]]+a[i]);
            }
        }
    }
    for(i=0;i<=m;i++){
        ans=max(ans,f[n][10000+i]);
        ans=max(ans,f[n][10000-i]);
    }
    cout<<ans<<endl;
    return 0;
}
View Code

 

posted @ 2021-02-09 11:16  朝暮不思  阅读(132)  评论(0编辑  收藏  举报