【01背包】失衡天平

失衡天平 (nowcoder.com)

题意:

思路:

这个是01背包的模板题

首先我们可以考虑搜索

n个武器,每个武器都有三个决策:放左边,放右边,不放

因此这样就构成了搜索的状态图(不是DP的状态图!)

 

 这样每个结点都会有三个出边,三条出边就代表着三个决策

然而,我们注意到,我们只考虑两个参数:由于最优子结构,整体最优一定是由局部最优转移而来,而如果我们这样搜索就会产生很多个一定不是最优的无用状态。而且,我们只需考虑搜索到的每个状态的总重量和左右盘子重量之差,因此,搜索到的很多形式上不同的状态实际上可以归成一类状态,这个其实就是无后效性原理。把这些搜索到的状态合并在一起构成的状态就是DP的状态,这样归并之后产生的状态图就是DP状态图。

构成图之后就可以考虑在DP的状态图中转移了,我们定义dp[i][j]为前i样物品进行选择后,左右重量差为j的时候最大重量是多少

那么它可以由三个状态转移过来:前面那个选了左,前面那个选了右,前面那个没选

因此转移方程为:

 dp[i][j]=max(dp[i-1][j],max(dp[i-1][abs(j-a[i])]+a[i],dp[i-1][j+a[i]]+a[i]));

Code:

#include <bits/stdc++.h>
using namespace std;
const int mxn=1e5+10;
int n,m;
int a[mxn],dp[110][mxn];
int main(){
    scanf("%d%d",&n,&m);
    memset(dp,128,sizeof(dp));
    dp[0][0]=0;
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=n;i++){
        for(int j=0;j<=mxn;j++) dp[i][j]=max(dp[i-1][j],max(dp[i-1][abs(j-a[i])]+a[i],dp[i-1][j+a[i]]+a[i]));
    }
    /*for(int i=1;i<=n;i++){
        for(int j=0;j<mxn;j++) printf("%d%c",dp[i][j],j==mxn-1?'\n':' ');
    }*/
    int ans=0;
    for(int i=0;i<=m;i++){
        ans=max(ans,dp[n][i]);
    }
    printf("%d\n",ans);
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值