nyoj 546 Divideing Jewels 第五届河南省程序设计大赛
2016-05-28 10:07
225 查看
Divideing Jewels
描述Mary and Rose own a collection of jewells. They want to split the collection among themselves so that both receive an equal share of the jewels. This would be easy if all the jewels had the same value, because then they could just split the collection in
half. But unfortunately, some of the jewels are larger, or more beautiful than others. So, Mary and Rose start by assigning a value, a natural number between one and ten, to each jewel. Now they want to divide the jewels so that each of them gets the same
total value. Unfortunately, they realize that it might be impossible to divide the jewels in this way (even if the total value of all jewels is even). For example, if there are one jewel of value 1, one of value 3 and two of value 4, then they cannot be split
into sets of equal value. So, they ask you to write a program that checks whether there is a fair partition of the jewels.
输入Each line in the input file describes one collection of jewels to be divided. The lines contain ten non-negative integers n1 , . . . , n10 , where ni is the number of jewels of value i. The maximum total number of jewells will be 10000.
The last line of the input file will be "0 0 0 0 0 0 0 0 0 0"; do not process this line.
输出For each collection, output "#k:", where k is the number of the test case, and then either "Can be divided." or "Can't be divided.".
Output a blank line after each test case.
样例输入
1 0 1 2 0 0 0 0 2 0
1 0 0 0 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0
样例输出
#1:Can't be divided.#
2:Can be divided.
多重背包问题要求很简单,就是每件物品给出确定的件数,求可得到的最大价值
多重背包转换成 01 背包问题就是多了个初始化,把它的件数C 用分解成若干个件数的集合,这里面数字可以组合成任意小于等于C的件数,而且不会重复,
之所以叫二进制分解,是因为这样分解可以用数字的二进制形式来解释
比如:7的二进制 7 = 111 它可以分解成 001 010 100 这三个数可以组合成任意小于等于7 的数,而且每种组合都会得到不同的数
15 = 1111 可分解成 0001 0010 0100 1000 四个数字
如果13 = 1101 则分解为 0001 0010 0100 0110 前三个数字可以组合成 7以内任意一个数,加上 0110 = 6 可以组合成任意一个大于6 小于13的数,虽然有重复但总是能把 13 以内所有的数都考虑到了,基于这种思想去把多件物品转换为,多种一件物品,就可用01 背包求解了。
看代码:
int n; //输入有多少种物品
int c; //每种物品有多少件
int v; //每种物品的价值
int s; //每种物品的尺寸
int count = 0; //分解后可得到多少种物品
int value[MAX]; //用来保存分解后的物品价值
int size[MAX]; //用来保存分解后物品体积
scanf("%d", &n); //先输入有多少种物品,接下来对每种物品进行分解
while (n--) { //接下来输入n中这个物品
scanf("%d%d%d", &c, &s, &v); //输入每种物品的数目和价值
for (int k=1; k<=c; k<<=1) { //<<右移 相当于乘二
value[count] = k*v;
size[count++] = k*s;
c -= k;
}
if (c > 0) {
value[count] = c*v;
size[count++] = c*s;
}
}
#include<stdio.h> #include<string.h> #define max(a,b) a>b?a:b int a[15],b[105]; int dp[100005]; int main(){ int t=0; while(1){ int sum=0,k=0; for(int i=1;i<=10;i++){ scanf("%d",&a[i]); sum+=a[i]*i; } if(sum==0) break; for(int i=1;i<=10;i++){ for(int j=1;j<=a[i];j<<=1){ b[k++]=j*i; a[i]-=j; } if(a[i]>0){ b[k++]=a[i]*i; a[i]=0; } } memset(dp,0,sizeof(dp)); for(int i=0;i<k;i++){ for(int j=sum/2;j>=b[i];j--) dp[j]=max(dp[j],dp[j-b[i]]+b[i]); } if(dp[sum/2]*2==sum) printf("#%d:Can be divided.\n\n",++t); else printf("#%d:Can't be divided.\n\n",++t); } return 0; }
相关文章推荐
- 12 个非常有用的 JavaScript Hacks
- jquery mobile界面数据刷新的实现方法
- Win8下安装theano和keras
- Android音频开发(1):基础知识
- ubuntu调试arduino程序出现找不到<string>
- java入门、java学习之java教程:Java语言编程简介
- Java设计模式之工厂模式
- Linux acpi off学习的必要
- 最近遇到.net framework安装不上问题1603问题号,原来是360捣鬼
- 设计模式---策略模式
- PowerPoint如何将演示文稿转换为WORD文档
- 近期资讯类
- 第二冲刺阶段——站立会议第四天5月28日
- 某项目docker化持续集成日记
- 第二冲刺阶段——个人工作总结04
- iOS教程:Core Data数据持久性存储基础教程
- PHP可变函数
- requests模块常用功能
- OpenCV基础知识
- 【C++】heap corruption detected错误调试总结及拓展