ZOJ-2059

31 篇文章 0 订阅

DP还是菜啊。。开始题意就没理解对,以为所有的材料都要用上,天真地用01背包做了,高度为总和的一半,果断WA。。后来翻看大神的题解,发现材料不必全部用完,只要能够组成相同高度的双塔,并输出最高的高度就行。。题解是用高度差为下标,低塔高度为值进行DP,每次状态转移有3种情况,把新材料放在低塔上,放在高塔上,不放进去,分别推最优解就行。。代码大部分参考自别人的,空间可以优化,别人用的滚动数组,我这边没有优化,感觉抄袭太多了已经,唉,接下来一定要自己好好思考啊

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

static int min(int a, int b)
{
	return a < b ? a : b;
}

static int max(int a, int b)
{
	return a > b ? a : b;
}

int main()
{
	int n, dp[100][2001];
	while (scanf("%d", &n), n >= 0)
	{
		memset(dp[0], -1, sizeof(dp[0]));
		dp[0][0] = 0;
		int num, i, k, d, new;
		for (k = 1; k <= n; k++)
		{
			scanf("%d", &num);
			memset(dp[k], -1, sizeof(dp[k]));
			for (i = 0; i <= 2000; i++)
				if (dp[k - 1][i] != -1)
				{
					d = abs(num - i);
					new = min(dp[k - 1][i] + num, dp[k - 1][i] + i);
					dp[k][d] = max(dp[k][d], new);
					d = num + i;
					if (d <= 2000)
						dp[k][d] = max(dp[k][d], dp[k - 1][i]);
					dp[k][i] = max(dp[k][i], dp[k - 1][i]);
				}
		}
		if (dp[n][0] == 0 || dp[n][0] == -1)
			puts("Sorry");
		else
			printf("%d\n", dp[n][0]);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值