1021 失衡天平 动态规划 线性DP 思维

链接:https://ac.nowcoder.com/acm/contest/24213/1021
来源:牛客网

题目描述

终于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)。
示例2

输入

复制
5 0
10 20 30 40 100

输出

复制
200

说明

称一次,(10,20,30,40 ; 100)。

分析

随着n增大,有三个增大的值,左边天平重量,右边天平重量,天平之间的差值

所求也是天平之间的差值,最终判断也是天平之间的差值,天平之间的差值也能直接二重循环得到一个时间复杂度最小的值。

所以设dp[i][j] 表示前i个元素,放到左右两边的天平上,差值的绝对值为j的最大质量。

由于差值是相对的,可能会有负值,所以加一个abs函数将两个天平的差值确定,毕竟两个天平是等价的。

最后输出差值为0到m之间的,天平重量的最大值。

 

//-------------------------代码----------------------------

#define int LL
const int N = 1e4+10,M = 110;
int n,m;

int a[N];
int dp[M][N];
void solve()
{
cin>>n>>m;
fo(i,1,n) cin>>a[i];
memset(dp,-0x3f,sizeof dp);
dp[0][0] = 0;
fo(i,1,n) {
fo(j,0,N) {
dp[i][j] = max({dp[i-1][abs(j-a[i])] + a[i],
dp[i-1][abs(j+a[i])] + a[i],
dp[i-1][j]});
}
}
int mx = 0;
fo(i,0,m) {
mx = max(mx,dp[n][i]);
}
cout<<mx<<endl;
}

signed main(){
clapping();TLE;

// int t;cin>>t;while(t -- )
solve();
// {solve(); }
return 0;
}

/*样例区


*/

//------------------------------------------------------------

posted @ 2022-07-07 15:49  er007  阅读(50)  评论(0编辑  收藏  举报