• Distribution of inheritance (diff)


    Description


    Jack and John inherited an inheritance, which includes (n) assets (including real estate, deposits, stocks, etc.), and the value of each asset is (a_i). Now they have to distribute the inheritance, but they cannot separate the individual assets. The distribution difference is the difference in the total value of their respective assets. Please allocate these (n) items to them in order, so that the maximum difference between the two persons at each step is the smallest.

    Format


    Input

    The first line is a positive integer (t(≤5)), which represents the number of data groups; in each group of data, the first line is a positive integer (n (≤300)), which represents the number of assets, and the second line is (n) positive integers (a_i)((≤100)), which represents The value of each property.

    Output

    For each set of data, output the answer.

    Sample


    Input

    2
    5
    1 2 1 4 3
    7
    4 5 6 1 1 3 4
    

    Output

    2
    5
    

    Sample Explanation

    In sample 1, the order of distribution of the five assets is: Jack, John, John, Jack, John, so at each step, the total value of their respective distribution of assets is ({1,0})({1,2})({1,3})({5,3})({5,6}), the distribution difference is 1 1 2 2 1, and the maximum is 2.

    Sample Code


    #include <cstdio>
    #include <cstring>
    const int N=305, AN=30000, INF=0x7f7f7f7f;
    int a[N], dp[N][AN*2+100];
    inline int mn(int x, int y){
    	return x>y ? y : x;
    }
    inline int mx(int x, int y){
    	return x<y ? y : x;
    }
    inline int ab(int x){
    	return x>0 ? x : -x;
    }
    int main(){
    	freopen("diff.in", "r", stdin);
    	freopen("diff.out", "w", stdout);
    	int t, n;
    	scanf("%d", &t);
    	while (t--){
    		scanf("%d", &n);
    		for (int i=1; i<=n; i++)	
    			scanf("%d", &a[i]);
    		memset(dp, 0x7f, sizeof dp);
    		dp[0][AN]=0;
    		for (int i=1; i<=n; i++)
    			for (int j=0; j<=AN*2; j++)
    				if (dp[i-1][j]!=INF){
    					dp[i][j+a[i]]=mn(dp[i][j+a[i]], mx(dp[i-1][j], ab(j+a[i]-AN)));
    					dp[i][j-a[i]]=mn(dp[i][j-a[i]], mx(dp[i-1][j], ab(j-a[i]-AN)));
    				}
    		int ans=INF;
    		for (int i=0; i<=AN; i++)
    			ans=mn(ans, dp[n][i]);
    		printf("%d
    ", ans);
    	}
    	return 0;
    }
    /*
    dp[i][j]表示前i件财物中两人所得总价值差值为j时的的最小差值,
    那么对于第i件财物有两种情况,给第一个人和给第二个人,进而有转移方程:
    dp[i][j+a[i]]=min(dp[i][j+a[i]],max(dp[i-1][j],abs(j+a[i]))
    dp[i][j-a[i]]=min(dp[i][j-a[i]],max(dp[i-1][j],abs(j-a[i]))
    max(dp[n][k])即为答案,-30000<=k<=30000
    所以需+30000进行下标偏移
    */ 
    
    
  • 相关阅读:
    考试总结 模拟69
    考试总结 模拟68
    考试总结 模拟67
    考试总结 模拟66
    20190722 NOIP模拟测试7 考后反思
    20190719 NOIP模拟测试6 (考后反思)
    星际旅行(欧拉路,欧拉回路)(20190718 NOIP模拟测试5)
    20190718 NOIP模拟测试5 考后反思
    [POJ2942]Knights of the Round Table(点双+二分图判定——染色法)
    奇袭(单调栈+分治+桶排)(20190716 NOIP模拟测试4)
  • 原文地址:https://www.cnblogs.com/jiupinzhimaguan/p/13806460.html
Copyright © 2020-2023  润新知