问题 D: 小李打怪兽(01背包)

时间限制: 1 Sec  内存限制: 128 MB
提交: 115  解决: 54
[提交] [状态] [讨论版] [命题人:外部导入]

题目描述

 小李对故乡的思念全部化作了对雾霾天气的怨念,这引起了掌控雾霾的邪神的极大不满,邪神派去了一只小怪兽去对付小李,由于这只怪兽拥有极高的IQ,它觉得直接消灭小李太没有难度了,它决定要和小李在智力水平上一较高下。我们可否帮助小李来战胜强大的怪兽呢? 

问题是这样的:给定一堆正整数,要求你分成两堆,两堆数的和分别为S1S2,谁分的方案使得 S1*S1-S2*S2的结果小(规定S1>=S2),谁就将获得胜利。 

注:S2可以等于0

 

输入

 

第一行n,表示共有n个数
第二行共n个用空格隔开的正整数ai,表示给定的一堆正整数。

 

输出

输出就一个整数,表示 S1*S1-S2*S2 的最小值。

 

样例输入

1 2 3 4 

 

样例输出

0

 

提示

 

14一堆,23一堆,5*5-5*5 = 0  

60%的数据,1<=n<=20

80%的数据,1<=n<=50ai<=20

100%的数据,1<=n<=100ai<=100


说实话我第一眼是排序贪心..然后分成两堆求,然后我自己举出了反例..这道题实际用01背包的知识点..我应该是最近在做线段树的模板题改模板和那种容易看出知识点的题做多了,变式题想不到相关知识点

先sort

s1*s1-s2*s2=(s1+s2)--(s1-s2),前面一个是总和。s1,s2,尽量往sum/2去靠,不妨令s2是小于sum/2的,然后在n个数去挑价值最大,每个数的价值同时是体积,背包的体积容量是sum/2.这时候,问题迎刃而解。

不妨总结一下,以后在碰到两边有一定关系的并且其中一边往某个边界靠的,试试01背包


#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std;
//不一定平均分的 
int a[100000];
int dp[100000];
int n;
long int sum;

int main(void)
{
		while(scanf("%d", &n)!=EOF)
		{
			sum=0;
		 	for(int i=1;i<=n;i++)
			 {
			 	scanf("%d",&a[i]);sum+=a[i];	
			 }	
			
			int c=sum/2;
		
			for(int i=1;i<=n;i++)
			{
				for(int j=c;j>=a[i];j--)
				{
					dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
				}
			}
				
		    printf("%d\n",sum*( (sum-dp[c])-dp[c] ) );
		
		}
return 0;
} 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值