先搞一下题目
——————————————————————————————————————————
标题
分配宝藏
类别
综合
时间限制
2S
内存限制
256Kb
问题描述
两个寻宝者找到一个宝藏,里面包含n件物品,每件物品的价值分别是W[0],W[1],…W[n-1]。
SumA代表寻宝者A所获物品价值总和,SumB代表寻宝者B所获物品价值总和,
请问怎么分配才能使得两人所获物品价值总和差距最小,
即两人所获物品价值总和之差的绝对值|SumA - SumB|最小。
也就是要使得其中一人所获物品价值与所有物品总价值的二分之一之差最小
因此可以将所有物品总价值的二分之一作为背包容量
此时物品的价值在作为价值的同时也作为物品的重量,因为挑选出来的物品的总价值不能超过所有物品总价值的二分之一,即挑选出来的物品的总重量不能超过背包容量
输入说明
输入数据由两行构成:
第一行为一个正整数n,表示物品个数,其中0<n<=200。
第二行有n个正整数,分别代表每件物品的价值W[i],其中0<W[i]<=200。
输出说明
对于每组数据,输出一个整数|SumA-SumB|,表示两人所获物品价值总和之差的最小值。
输入样例
4
1 2 3 4
输出样例
0
——————————————————————————————————————————
一般的解法是0-1背包,我有一些不同的见解(●'◡'●)(自我感觉良好)
话不多说,上代码。
//0-1背包;分宝藏
#include <stdio.h>
#include <math.h>
int maxout(int *value,int n);
int value[1024];
int asum,bsum;
int main(){
int n,i,j,max;
bool turn=0;//0:a选 1:b选
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&value[i]);
//
do{
max=maxout(value,n);
switch(turn){
case false:
asum+=max;
if(asum>bsum)
turn=true;
break;
case true:
bsum+=max;
if(bsum>asum)
turn=false;
break;
}
}while(max!=0);
printf("%d",abs(asum-bsum));
}
int maxout(int *value,int n){
int i,max,loc;//找出最大值,并返回
max=0;
for(i=0;i<n;i++){
if(value[i]>max){
max=value[i];
loc=i;
}
}
value[loc]=0;//而后将其变为0
return max;
}
思路说明,A,B两个人轮流选宝藏,一次拿一个,就普遍理性来说(bushi),肯定是要捡价值大的拿嘛~但是可能出现A:100,B:1 ,A:99,B:1...为了公平,我们设置了一个规则:当A的财宝总价值大于B的时候就要换人,否则可以一直拿。对B来说也是这样。
0-1背包固然是一个系统的算法,但有时候换个角度看问题,会简单很多ψ(`∇´)ψ
嘛~各位新春快乐~
23/1/26