• POJ2576 Tug of War 二维背包


    题目大意

    一群人拔河,给出每个人的重量,要求两队人数之差不超过1人,且每队总重量之差最小。

    思路

    选出严格总人数一半(或+1)的人为一队,在该队重量不超过所有人总重量一半的情况下,使其重量最大。

    人数一维,最终结果严格为其最大限制:总人数一半;队总重量一维,最终结果尽量大,不一定为其最大限制:所有人总重量一半。

    所以初始化时,应将DP数组初始化为-∞,循环结束时,在DP[totV]中求最大值。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdarg>
    using namespace std;
    
    const int MAX_W = 23000, MAX_V = 55, MAX_ORG = 110;
    
    int _max(int a, int b)
    {
    	return b == 0 ? a : max(a, b);
    }
    
    int Dp(int totV, int totObj, int totW, int *objW)
    {
    	static int DP[MAX_W][MAX_V];
    	memset(DP, 0xcf, sizeof(DP));
    	DP[0][0] = 0;
    	for (int obj = 1; obj <= totObj; obj++)
    		for (int w = totW; w >= objW[obj]; w--)
    			for (int v = totV; v >= 1; v--)
    				DP[w][v] = _max(DP[w][v], DP[w - objW[obj]][v - 1] + objW[obj]);
    	int ans = 0;
    	for (int i = 0; i <= totW; i++)
    		ans = max(ans, DP[i][totV]);
    	return ans;
    }
    
    int main()
    {
    #ifdef _DEBUG
    	freopen("c:\noi\source\input.txt", "r", stdin);
    #endif
    	int n, sum = 0, ws[MAX_ORG];
    	memset(ws, 0, sizeof(ws));
    	scanf("%d", &n);
    	for (int i = 1; i <= n; i++)
    	{
    		scanf("%d", i + ws);
    		sum += ws[i];
    	}
    	int lighter = Dp(n / 2, n, (sum + 1) / 2, ws);
    	if ((n / 2) * 2 != n)
    		lighter = max(lighter, Dp(n / 2 + 1, n, (sum + 1) / 2, ws));
    	int weighter = sum - lighter;
    	if (lighter > weighter)
    		swap(lighter, weighter);
    	printf("%d %d
    ", lighter, weighter);
    	return 0;
    }
    

      

  • 相关阅读:
    系统分析师考试
    系统分析师
    软件设计师考试
    海恩法则”的启示:制度不落到实处事故必发
    eclipse下生成Java类图和时序图,生成UML图
    bzoj4010【HNOI2015】菜肴制作
    atitit.提升开发效率---MDA 软件开发方式的革命(5)----列表查询建模
    【数据结构和算法16】堆排序
    这一路走来,冷暖自知 (附算法demos)
    c++实现二叉搜索树
  • 原文地址:https://www.cnblogs.com/headboy2002/p/8502900.html
Copyright © 2020-2023  润新知