题意:
一
共
有
n
个
武
器
,
每
个
武
器
重
量
为
w
i
一共有n个武器,每个武器重量为w_i
一共有n个武器,每个武器重量为wi
有
一
个
天
平
,
往
天
平
两
端
放
武
器
有一个天平,往天平两端放武器
有一个天平,往天平两端放武器
如
果
天
平
两
端
的
重
量
小
于
等
于
m
那
么
可
以
全
部
取
走
如果天平两端的重量小于等于m那么可以全部取走
如果天平两端的重量小于等于m那么可以全部取走
问
最
多
能
取
走
多
少
重
量
武
器
问最多能取走多少重量武器
问最多能取走多少重量武器
题解:
n
,
w
i
,
m
<
=
100
n,w_i,m<=100
n,wi,m<=100
这
个
天
平
可
以
多
次
取
这个天平可以多次取
这个天平可以多次取
但
其
实
思
考
一
下
,
会
发
现
如
果
你
x
次
能
把
某
两
种
物
品
取
走
但其实思考一下,会发现如果你x次能把某两种物品取走
但其实思考一下,会发现如果你x次能把某两种物品取走
那
么
这
2
∗
x
种
物
品
同
时
放
的
时
候
也
一
定
能
取
走
那么这2*x种物品同时放的时候也一定能取走
那么这2∗x种物品同时放的时候也一定能取走
只
不
过
是
放
的
顺
序
交
换
一
下
之
类
的
关
系
只不过是放的顺序交换一下之类的关系
只不过是放的顺序交换一下之类的关系
所
以
我
们
现
在
需
要
维
护
的
状
态
有
已
枚
举
的
武
器
,
差
值
,
最
大
重
量
所以我们现在需要维护的状态有已枚举的武器,差值,最大重量
所以我们现在需要维护的状态有已枚举的武器,差值,最大重量
所
以
d
p
数
组
就
出
来
了
,
d
p
[
i
]
[
j
]
表
示
前
i
个
武
器
中
差
值
为
j
的
最
大
重
量
所以dp数组就出来了,dp[i][j]表示前i个武器中差值为j的最大重量
所以dp数组就出来了,dp[i][j]表示前i个武器中差值为j的最大重量
对
于
第
i
种
武
器
的
转
移
方
法
就
是
对于第i种武器的转移方法就是
对于第i种武器的转移方法就是
让
差
值
加
这
个
武
器
,
即
把
这
个
武
器
放
到
较
重
的
一
端
让差值加这个武器,即把这个武器放到较重的一端
让差值加这个武器,即把这个武器放到较重的一端
新
的
差
值
为
这
个
武
器
和
当
前
差
值
的
绝
对
值
,
即
放
到
轻
的
一
段
新的差值为这个武器和当前差值的绝对值,即放到轻的一段
新的差值为这个武器和当前差值的绝对值,即放到轻的一段
还
有
就
是
不
选
这
个
武
器
,
三
种
方
程
分
别
为
还有就是不选这个武器,三种方程分别为
还有就是不选这个武器,三种方程分别为
d
p
[
i
]
[
j
+
a
i
]
+
a
i
dp[i][j+a_i]+a_i
dp[i][j+ai]+ai
d
p
[
i
]
[
a
b
s
(
j
−
a
i
)
]
+
a
i
dp[i][abs(j-a_i)]+a_i
dp[i][abs(j−ai)]+ai
d
p
[
i
]
[
j
−
1
]
dp[i][j-1]
dp[i][j−1]
这
三
种
状
态
取
最
大
即
可
这三种状态取最大即可
这三种状态取最大即可
最
后
只
要
找
出
差
值
不
超
过
m
的
最
大
重
量
最后只要找出差值不超过m的最大重量
最后只要找出差值不超过m的最大重量
AC代码
/*
Author:zzugzx
Lang:C++
Blog:blog.csdn.net/qq_43756519
*/
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
#define SZ(x) (int)x.size()
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double,double> pdd;
const int mod=1e9+7;
//const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=1e6+10;
const ll inf=0x3f3f3f3f;
const int dir[8][2]={{0,1},{1,0},{0,-1},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1}};
int dp[110][11000],a[110];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,m,N=10000;
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
memset(dp,-inf,sizeof dp);
dp[0][0]=0;
for(int i=1;i<=n;i++)
for(int j=0;j<=N;j++){
dp[i][j]=dp[i-1][j];
int tmp=max(dp[i-1][j+a[i]]+a[i],dp[i-1][abs(j-a[i])]+a[i]);
dp[i][j]=max(dp[i][j],tmp);
}
int ans=0;
for(int i=0;i<=m;i++)
ans=max(ans,dp[n][i]);
cout<<ans;
return 0;
}