HDU——1059Dividing(母函数或多重背包)
Dividing
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 23277 Accepted Submission(s): 6616
half. But unfortunately, some of the marbles are larger, or more beautiful than others. So, Marsha and Bill start by assigning a value, a natural number between one and six, to each marble. Now they want to divide the marbles so that each of them gets the
same total value.
Unfortunately, they realize that it might be impossible to divide the marbles in this way (even if the total value of all marbles is even). For example, if there are one marble 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 marbles.
0 0''. The maximum total number of marbles will be 20000.
The last line of the input file will be ``0 0 0 0 0 0''; do not process this line.
Output a blank line after each test case.
1 0 0 0 1 1
0 0 0 0 0 0
Can't be divided.
Collection #2:
Can be divided.
看看能否凑出V/2这个值就可以了。母函数比较好理解
代码:
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
#define INF 0x3f3f3f3f
#define MM(x) memset(x,0,sizeof(x))
#define MMINF(x) memset(x,INF,sizeof(x))
typedef long long LL;
const double PI=acos(-1.0);
const int N=1300;
int c[7];
int c1[N],c2[N];
int main(void)
{
int i,j,k,V,tcase=0;
while (~scanf("%d%d%d%d%d%d",&c[1],&c[2],&c[3],&c[4],&c[5],&c[6]))
{
V=0;
for (i=1; i<=6; i++)
{
c[i]%=60;
V+=c[i]*i;
}
if(!V)
break;
if(V&1)
{
printf("Collection #%d:\nCan't be divided.\n\n",++tcase);
continue;
}
V>>=1;
MM(c1);MM(c2);
int index=0;
for (i=1; i<=6; i++)
{
if(c[i])
{
for (j=0; j<=c[i]; j++)
{
c1[j*i]=1;
index=i;
}
break;
}
}
for (i=index+1; i<=6; i++)
{
for (j=0; j<=V; j++)
{
if(c1[j])
{
for (k=0; k<=c[i]; k++)
{
if(j+i*k>V)
break;
c2[j+i*k]+=c1[j];
}
}
}
memcpy(c1,c2,sizeof(c2));
MM(c2);
}
printf("Collection #%d:\n",++tcase);
puts(c1[V]?"Can be divided.\n":"Can't be divided.\n");
MM(c);
}
return 0;
}
然后是多重背包的。感觉以后这样的题还是写成自定义函数吧。不然课件上非常难看懂。
代码:
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
#define INF 0x3f3f3f3f
#define MM(x) memset(x,0,sizeof(x))
#define MMINF(x) memset(x,INF,sizeof(x))
typedef long long LL;
const double PI=acos(-1.0);
const int N=122000;
int dp[N];
int V;
int c[7];
void zonepack(int cost,int val)
{
for (int i=V; i>=cost ; --i)
{
dp[i]=max(dp[i],dp[i-cost]+val);
}
}
void wanquanpack(int cost,int val)
{
for (int i=cost; i<=V ; ++i)
{
dp[i]=max(dp[i],dp[i-cost]+val);
}
}
int main(void)
{
int n,i,j,k,tcase=0,cnt;
while (~scanf("%d%d%d%d%d%d",&c[1],&c[2],&c[3],&c[4],&c[5],&c[6])&&(c[1]||c[2]||c[3]||c[4]||c[5]||c[6]))
{
cnt=0;
V=0;
for (i=1; i<=6; i++)
V+=c[i]*i;
if(V&1)
{
printf("Collection #%d:\n%s\n\n",++tcase,"Can't be divided.");
continue;
}
V>>=1;
MM(dp);
for (i=1; i<=6; i++)
{
if(c[i]*i>=V)
{
wanquanpack(i,i);
}
else
{
int k=1,t=c[i];
while (k<t)
{
zonepack(k*i,k*i);
t-=k;
k<<=1;
}
zonepack(t*i,t*i);
}
}
printf("Collection #%d:\n%s\n\n",++tcase,dp[V]!=V?"Can't be divided.":"Can be divided.");
}
return 0;
}
HDU——1059Dividing(母函数或多重背包)的更多相关文章
- HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化)
HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化) 题意分析 先把每种硬币按照二进制拆分好,然后做01背包即可.需要注意的是本题只需要求解可以凑出几种金钱的价格,而不需要输出种数 ...
- HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化)
HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化) 题意分析 给出一系列的石头的数量,然后问石头能否被平分成为价值相等的2份.首先可以确定的是如果石头的价值总和为奇数的话,那 ...
- hdu 2844 Coins (多重背包)
题意是给你几个数,再给你这几个数的可以用的个数,然后随机找几个数来累加, 让我算可以累加得到的数的种数! 解题思路:先将背包初始化为-1,再用多重背包计算,最后检索,若bb[i]==i,则说明i这个数 ...
- hdu 1059 Dividing bitset 多重背包
bitset做法 #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a ...
- HDU 2844 Coins(多重背包)
点我看题目 题意 :Whuacmers有n种硬币,分别是面值为A1,A2,.....,An,每一种面值的硬币的数量分别是C1,C2,......,Cn,Whuacmers想买钱包,但是想给人家刚好的钱 ...
- HDU 2844 Coins 【多重背包】(模板)
<题目连接> 题目大意: 一位同学想要买手表,他有n种硬币,每种硬币已知有num[i]个.已知手表的价钱最多m元,问她用这些钱能够凑出多少种价格来买手表. 解题分析: 很明显,这是一道多重 ...
- 题解报告:hdu 1059 Dividing(多重背包、多重部分和问题)
Problem Description Marsha and Bill own a collection of marbles. They want to split the collection a ...
- hdu(1171)多重背包
hdu(1171) Big Event in HDU Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (J ...
- hdu 5445 Food Problem 多重背包
Food Problem Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5 ...
随机推荐
- python-mysql软件下载地址
http://sourceforge.net/projects/mysql-python/?source=dlp
- JBOSS默认连接池配置
jboss5.0mysql连接配置 <?xml version="1.0" encoding="UTF-8"?> <!-- The Hyper ...
- POJ 2486 Apple Tree (树形DP,树形背包)
题意:给定一棵树图,一个人从点s出发,只能走K步,每个点都有一定数量的苹果,要求收集尽量多的苹果,输出最多苹果数. 思路: 既然是树,而且有限制k步,那么树形DP正好. 考虑1个点的情况:(1)可能在 ...
- MATLAB批量修改图片名称
申明:转载请注明出处. 设在“D:\UserDesktop\pic\”目录下有很多张格式为jpg照片,命名不规则,如图. 现在用MATLAB批量修改所有图片的命名格式,改为1.jpg,2.jpg,.. ...
- codevs 1606 台阶
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 话说某牛家门外有一台阶,这台阶可能会很高(总层数<=1000000). 这 ...
- abp viewmodel的写法
我的写法 public class QuotaCreateOrEditViewModel { public QuotaDto LoanQuota { get; set; } public bool I ...
- Linux基础学习-chrony时间同步服务
Chrony时间同步 NTP(Network Time Protocol,网络时间协议)是用来使网络中的各个计算机时间同步的一种协议.它的用于是把计算机的时钟同步到世界协调时UTC,其精度在局域网内可 ...
- 命令行发送UDP
https://www.cnblogs.com/Dennis-mi/articles/6866762.html: 如果往本地UDP端口發送數據,那麼可以使用以下命令:echo “hello” > ...
- 初遇Linux
Ctrl+Alt+(F1-F6):切换虚拟终端 Ctrl+Alt:鼠标切换界面 $:普通用户登录后系统的提示符 #:root用户登录后系统的提示符 Linux命令 exit 用于退出目前的shell ...
- perl学习之裸字
use strict包含3个部分.其中之一(use strict "subs")负责禁止乱用的裸字. 这是什么意思呢? 如果没有这个限制,下面的代码也可以打印出"hell ...