题干:
Dwik and his brother Samir both received scholarships from a famous university in India. Their father, Besher, wants to send some money with each of them.
Besher has n coins, the ith coin has a value of ai. He will distribute these coins between his two sons in n steps. In the ith step, he chooses whether to give the ithcoin to Dwik or to Samir.
Let xi be the absolute difference between the sum of Dwik's and Samir's coins after the ith step. The unfairness factor of a distribution is max({x1, x2, ..., xn}). Besher wants to minimize the unfairness factor, can you help him?
Input
The first line of the input consists of a single integer t, the number of test cases. Each test case consists of 2 lines:
The first line contains an integer n (1 ≤ n ≤ 100).
The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 100).
Output
Print t lines, ith line containing a single integer, the answer to the ith test case.
Example
Input
2
5
1 2 1 4 3
7
4 5 6 1 1 3 4
Output
2
5
Note
In the first sample test, besher has 5 coins (1, 2, 1, 4, 3), he can distribute them in the following way:
Step 1: Give the first coin to dwik , d = 1, s = 0 x1 = |1 - 0| = 1
Step 2: Give the second coin to samir, d = 1, s = 2 x2 = |1 - 2| = 1
Step 3: Give the third coin to samir, d = 1, s = 3 x3 = |1 - 3| = 2
Step 4: Give the fourth coin to dwik, d = 5, s = 3 x4 = |5 - 3| = 2
Step 5: Give the fifth coin to samir, d = 5, s = 6 x5 = |5 - 6| = 1
max({x1, x2, x3, x4, x5}) = 2
解题报告:
直接dp[i][j]代表前i个物品其中A这个人选择了总价值为j的容量的最小化最大差值。
注意代码逻辑,所以要算两个转移的时候分别取最大值,然后取个最小值赋值给dp[i][j],
而不能每次都dp[i][j]=min(dp[i][j],max())。其实如果用我为人人的写法的话就可以避免这个问题。
(然而好像也可以直接每次都更新dp[i][j]呀?)
AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define F first
#define S second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2e4 + 5;
int dp[105][MAX],a[MAX],sum[MAX];
int ZERO = 1e4,n;
int main()
{int t;cin>>t;while(t--) {scanf("%d",&n);for(int i = 1; i<=n; i++) scanf("%d",a+i),sum[i] = sum[i-1] + a[i];memset(dp,0x3f,sizeof dp);int inf = dp[0][0];dp[0][0]=0;for(int i = 1; i<=n; i++) {for(int j = 0; j<=sum[n]; j++) {int curA = j,curB = sum[i] - j;int cA = j,cB = sum[i] - cA;int tmp1=0x3f3f3f3f,tmp2=0x3f3f3f3f;tmp1 = max(dp[i-1][j],abs(curA-curB));//把第i个放入B中 if(j >= a[i])tmp2 = max(dp[i-1][j-a[i]],abs(cA-cB));//把第i个放入A中 dp[i][j] = min(tmp1,tmp2);}}int ans = 0x3f3f3f3f;for(int i = 0; i<MAX; i++) ans = min(ans,dp[n][i]);printf("%d\n",ans);} return 0 ;
}
这题还可以用记忆化或者二分写,思路差不多,光贴个代码吧: