牛客每日一题NC19158失衡天平 (动态规划dp)

https://ac.nowcoder.com/acm/problem/19158

题目描述

终于Alice走出了大魔王的陷阱,可是现在傻傻的她忘了带武器了,这可如何是好???这个时候,一个神秘老人走到她面前答应无偿给她武器,但老人有个条件,需要将所选武器分别放在天平的两端,若天平平衡则可以将天平上的所有武器拿走,还好这个天平锈迹斑斑,只要两端重量相差小于等于m就会保持平衡,Alice傻傻的认为越重的武器越好,求Alice最多能拿走的武器总重量。(不限操作次数)

输入描述:

第一行2个整数 n, m;
第二行n个整数x,分别表示n件武器的重量。
1 <= n <= 100; 0 <= m <= 100; 1 <= x <= 100;

输出描述:

一个整数,表示Alice最多能拿走的武器总重量。
示例1

输入

5 4
1 5 61 65 100

输出

132

说明

可以称两次,第1次:(1 ; 5),第二次(61 ; 65)。

 

题意:给n个武器的重量,放在天平两端相差不超过m就可以拿走,问最多能拿走多少重量?

题解:我们用dp[i][j]表示到第i个物品重量相差为j的重量最大值

转移状态 ① 不要这个武器 dp[i][j]=dp[i-1][j];

     ②把这个武器放在天平右边 dp[i][ j+a[i] ] = max(dp[i][ j+a[i] ] , dp[i-1][j] +a[i]  );

     ③把这个武器放在天平左边 dp[i][ j- a[i] ] = max(dp[i][ j- a[i] ] , dp[i-1][j] +a[i] );

因为重量差值可能会出现负数,我们倍长数组 

起点 dp[0][10000]=0;

答案就是对所有dp[n][ ] 取max;

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f 
using namespace std;
const int maxn= 107;
int x[maxn];
int dp[maxn][2*maxn*maxn];
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&x[i]);
    }
    memset(dp,-inf,sizeof(dp));
    dp[0][10000]=0;
    for(int i=1;i<=n;i++){
        for(int j=0;j<=20000;j++){
            dp[i][j]=max(dp[i-1][j], dp[i][j] );
            if(j+x[i]<=20000) dp[i][j+x[i]]=max(dp[i][j+x[i]],dp[i-1][j]+x[i]);
            if(j-x[i]>=0 ) dp[i][j-x[i]] =max(dp[i][j-x[i]] , dp[i-1][j]+x[i] );
        }
    }
    int ans=0;
    for(int i=0;i<=m;i++){
        ans=max(ans,dp[n][10000+i]);
        ans=max(ans,dp[n][10000-i]);
    }
    printf("%d\n",ans);
    return 0;
}
View Code

 

posted @ 2020-07-30 14:07  杰瑞与汤姆  阅读(267)  评论(0编辑  收藏  举报