shu7-19【背包和母函数练习】
题目:http://acm.hdu.edu.cn/diy/contest_show.php?cid=20083
密码:shuacm
感觉他们学校的新生训练出的比较好。
今天很多题目都是强化了背包的转化。
关于背包转化成求最优解见分析:点击打开链接
贴个背包的模板:
//0-1背包, 代价为 cost, 获得的价值为 weight
// 每种物品最多只可以选一次
void ZeroOnePack(int cost, int weight)
{
for(int i = nValue; i >= cost; i--)
dp[i] = dp[i] + dp[i-cost]+weight;
} // 完全背包,代价为 cost, 获得的价值为 weight
// 每种物品可以选无限次, 或者在可选的有限次内能够装满背包
void CompletePack(int cost, int weight)
{
for(int i = cost; i <= nValue; i++)
dp[i] = dp[i] + dp[i-cost]+weight;
} //多重背包
//每种物品可以选有限次
void MultiplePack(int cost, int weight, int amount)
{
if(cost*amount >= nValue) CompletePack(cost, weight); else
{
int k = 1;
while(k < amount)
{
ZeroOnePack(k*cost, k*weight);
amount -= k;
k <<= 1;
}
ZeroOnePack(amount*cost, amount*weight);
}
}
关于转化后,除掉 weight,把 max 换成 sum 即可,具体分析见上面的博客
void ZeroOnePack(int cost)
{
for(int i = nValue; i >= cost; i--)
dp[i] = dp[i] + dp[i-cost];
} void CompletePack(int cost)
{
for(int i = cost; i <= nValue; i++)
dp[i] = dp[i] + dp[i-cost];
} void MultiplePack(int cost, int amount)
{
if(cost*amount >= nValue) CompletePack(cost); else
{
int k = 1;
while(k < amount)
{
ZeroOnePack(k*cost);
amount -= k;
k <<= 1;
}
ZeroOnePack(amount*cost);
}
}
A
和上面分析博客一样有木有
Problem A
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 40 Accepted Submission(s) : 32
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
"The second problem is, given an positive integer N, we define an equation like this:
N=a[1]+a[2]+a[3]+...+a[m];
a[i]>0,1<=m<=N;
My question is how many different equations you can find for a given N.
For example, assume N is 4, we can find:
4 = 4;
4 = 3 + 1;
4 = 2 + 2;
4 = 2 + 1 + 1;
4 = 1 + 1 + 1 + 1;
so the result is 5 when N is 4. Note that "4 = 3 + 1" and "4 = 1 + 3" is the same in this problem. Now, you do it!"
Input
Output
Sample Input
4
10
20
Sample Output
5
42
627
#include<stdio.h>
#include<string.h> const int maxn = 150;
int dp[maxn]; int main()
{
int n;
while(scanf("%d", &n) != EOF)
{
memset(dp,0,sizeof(dp));
dp[0] = 1;
for(int i = 1; i <= n; i++)
for(int j = i; j <= n; j++)
dp[j] += dp[j-i];
printf("%d\n", dp[n]); }
return 0;
}
B:母函数,待看中
为毛背包连样例 都 没有 出。。。感觉和 F 一样啊
Problem B
Time Limit : 1000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 23 Accepted Submission(s) : 18
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
Input
每组数据的第一行是两个整数n(1 <= n <= 40),k(1 <= k <= 8)。
接着有k行,每行有两个整数a(1 <= a <= 8),b(1 <= b <= 10),表示学分为a的课有b门。
Output
Sample Input
2
2 2
1 2
2 1
40 8
1 1
2 2
3 2
4 2
5 8
6 9
7 6
8 8
Sample Output
2
445
直接套用母函数模板,背包还是没有想出来。。。没道理啊
#include<stdio.h>
#include<string.h> const int maxn = 1000000;
int c1[maxn];
int c2[maxn]; int a[10];
int b[10]; int main()
{
int T;
int n,k;
scanf("%d", &T);
while(T--)
{
memset(c1, 0, sizeof(c1));
memset(c2, 0, sizeof(c2));
c1[0] = 1;
scanf("%d%d", &n,&k);
for(int i = 1; i <= k; i++)
{
scanf("%d%d", &a[i],&b[i]);
} for(int i = 1; i <= k; i++) //有几种学分, 第几层括号
{
for(int j = 0; j <= n; j++) //在原有的基础上遍历
{
for(int t = 0; t+j <= n && t <= a[i]*b[i]; t += a[i]) //遍历第 i 层括号的每一项
{//每种学分选的次数有限制,所以同时 k 也不能超过当前总的
c2[t+j] += c1[j];
}
} for(int j = 0; j <= n; j++)
{
c1[j] = c2[j];
c2[j] = 0;
}
}
printf("%d\n", c1[n]);
}
return 0;
}
C :背包总容量改为总价值的一半,尽量装满背包。所求的最大体积则是第二个答案
第一个答案 = 总价值-第一个答案
注意:<= 0非法输入,跳出。而不是 n == -1 退出。
Problem C
Time Limit : 10000/5000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 39 Accepted Submission(s) : 11
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
The splitting is absolutely a big event in HDU! At the same time, it is a trouble thing too. All facilities must go halves. First, all facilities are assessed, and two facilities are thought to be same if they have the same value. It is assumed that there is
N (0<N<1000) kinds of facilities (different value, different kinds).
Input
facilities) each. You can assume that all V are different.
A test case starting with a negative integer terminates input and this test case is not to be processed.
Output
Sample Input
2
10 1
20 1
3
10 1
20 2
30 1
-1
Sample Output
20 10
40 40
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std; const int maxn = 50*50*100+10;
int dp[maxn];
int nValue; int v[60];
int m[60]; void ZeroOnePack(int cost)
{
for(int i = nValue; i >= cost; i--)
dp[i] = dp[i] + dp[i-cost];
} void CompletePack(int cost)
{
for(int i = cost; i <= nValue; i++)
dp[i] = dp[i] + dp[i-cost];
} void MultiplePack(int cost, int amount)
{
if(cost*amount >= nValue) CompletePack(cost); else
{
int k = 1;
while(k < amount)
{
ZeroOnePack(k*cost);
amount -= k;
k <<= 1;
}
ZeroOnePack(amount*cost);
}
} int main()
{
int n;
while(scanf("%d", &n) != EOF)
{
if(n <= 0) break;
int sum = 0; for(int i = 0; i < n; i++)
{
scanf("%d%d", &v[i], &m[i]);
sum += v[i]*m[i];
}
nValue = sum/2; memset(dp,0,sizeof(dp));
dp[0] = 1; for(int i = 0; i < n; i++)
{
MultiplePack(v[i], m[i]);
} int ans1, ans2;
for(int i = nValue; i >= 0 ; i--)
{
if(dp[i] != 0)
{
ans2 = i;
break;
}
}
ans1 = sum-ans2;
printf("%d %d\n", ans1, ans2);
} return 0;
}
D:完全背包
Problem D
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 25 Accepted Submission(s) : 20
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
available in Silverland.
There are four combinations of coins to pay ten credits:
ten 1-credit coins,
one 4-credit coin and six 1-credit coins,
two 4-credit coins and two 1-credit coins, and
one 9-credit coin and one 1-credit coin.
Your mission is to count the number of ways to pay a given amount using coins of Silverland.
Input
Output
Sample Input
2
10
30
0
Sample Output
1
4
27
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std; int dp[310];
int a[20];
int nValue; void CompletePack(int cost)
{
for(int i = cost; i <= nValue; i++)
dp[i] = dp[i] + dp[i-cost];
} int main()
{
while(scanf("%d", &nValue) != EOF)
{
if(nValue == 0) break;
for(int i = 1; i <= 17; i++)
a[i] = i*i;
memset(dp,0,sizeof(dp));
dp[0] = 1; for(int i = 1; i <= 17; i++)
CompletePack(a[i]);
printf("%d\n", dp[nValue]);
}
}
E:不会
Problem E
Time Limit : 30000/15000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 4 Accepted Submission(s) : 1
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
select some stones and arrange them in line to form a beautiful pattern. After several arrangements he finds it very hard for him to enumerate all the patterns. So he asks you to write a program to count the number of different possible patterns. Two patterns
are considered different, if and only if they have different number of stones or have different colors on at least one position.
Input
available stones of each color respectively. All the input numbers will be nonnegative and no more than 100.
Output
which is a prime number.
Sample Input
3
1 1 1
2
1 2
Sample Output
Case 1: 15
Case 2: 8
Hint
BGM; BMG; GBM; GMB; MBG; MGB.
F:多重背包求解
Problem F
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 79 Accepted Submission(s) : 23
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
“Oh, God! How terrible! ”

Don’t be so afraid, guys. Although he hides in a cave of Hang Zhou, he dares not to go out. Laden is so bored recent years that he fling himself into some math problems, and he said that if anyone can solve his problem, he will give himself up!
Ha-ha! Obviously, Laden is too proud of his intelligence! But, what is his problem?
“Given some Chinese Coins (硬币) (three kinds-- 1, 2, 5), and their number is num_1, num_2 and num_5 respectively, please output the minimum value that you cannot pay with given coins.”
You, super ACMer, should solve the problem easily, and don’t forget to take $25000000 from Bush!
Input
Output
Sample Input
1 1 3
0 0 0
Sample Output
4
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std; const int maxn = 8000+10;
int dp[maxn];
int nValue; void ZeroOnePack(int cost)
{
for(int i = nValue; i >= cost; i--)
dp[i] = dp[i] + dp[i-cost];
} void CompletePack(int cost)
{
for(int i = cost; i <= nValue; i++)
dp[i] = dp[i] + dp[i-cost];
} void MultiplePack(int cost, int amount)
{
if(cost*amount >= nValue) CompletePack(cost); else
{
int k = 1;
while(k < amount)
{
ZeroOnePack(k*cost);
amount -= k;
k <<= 1;
}
ZeroOnePack(amount*cost);
}
} int main()
{
int a,b,c;
while(scanf("%d%d%d", &a,&b,&c) != EOF)
{
if(a == 0 && b == 0 && c == 0) break; memset(dp,0,sizeof(dp));
dp[0] = 1;
nValue = 1*a+2*b+5*c; MultiplePack(1, a);
MultiplePack(2, b);
MultiplePack(5, c); for(int i = 0; i < maxn; i++)
{
if(dp[i] == 0)
{
printf("%d\n", i);
break;
}
}
}
return 0;
}
G:签到。。。
Problem G
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 45 Accepted Submission(s) : 40
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
什么问题?他研究的问题是蟠桃一共有多少个!
不过,到最后,他还是没能解决这个难题,呵呵^-^
当时的情况是这样的:
第一天悟空吃掉桃子总数一半多一个,第二天又将剩下的桃子吃掉一半多一个,以后每天吃掉前一天剩下的一半多一个,到第n天准备吃的时候只剩下一个桃子。聪明的你,请帮悟空算一下,他第一天开始吃的时候桃子一共有多少个呢?
Input
Output
Sample Input
2
4
Sample Output
4
22
#include<stdio.h> int main()
{
int n;
while(scanf("%d", &n) != EOF)
{
int ans = 1;
while(--n)
{
ans = (ans+1)*2;
}
printf("%d\n", ans);
}
return 0;
}
shu7-19【背包和母函数练习】的更多相关文章
- Big Event in HDU(HDU1171)可用背包和母函数求解
Big Event in HDU HDU1171 就是求一个简单的背包: 题意:就是给出一系列数,求把他们尽可能分成均匀的两堆 如:2 10 1 20 1 结果是:20 10.才最均匀! 三 ...
- 钱币兑换问题_完全背包&&拆分&&母函数
ps:原来用新浪,可是代码的排版不是很好,所以用博客园啦,先容许我把从八月份开始的代码搬过来,从这里重新出发,希望这里可以一直见证我的成长. Time Limit: 2000/1000 MS (Jav ...
- 2079 ACM 选课时间 背包 或 母函数
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2079 题意:同样的学分 ,有多少种组合数,注意同样学分,课程没有区别 思路:两种方法 背包 母函数 背包: ...
- HDU 1059 Dividing 分配(多重背包,母函数)
题意: 两个人共同收藏了一些石头,现在要分道扬镳,得分资产了,石头具有不同的收藏价值,分别为1.2.3.4.5.6共6个价钱.问:是否能公平分配? 输入: 每行为一个测试例子,每行包括6个数字,分别对 ...
- hdu 1171 Big Event in HDU (01背包, 母函数)
Big Event in HDU Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- hdu 1171 (背包或者母函数问题)
Problem Description Nowadays, we all know that Computer College is the biggest department in HDU. Bu ...
- Holding Bin-Laden Captive!(1.多重背包 2.母函数)
Holding Bin-Laden Captive! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/ ...
- hdu 1028 Ignatius and the Princess III(母函数)
题意: N=a[1]+a[2]+a[3]+...+a[m]; a[i]>0,1<=m<=N; 例如: 4 = 4; 4 = 3 + 1; 4 = 2 + 2; 4 = 2 + ...
- HDU 1284(钱币兑换 背包/母函数)
与 HDU 1028 相似的题目. 方法一:完全背包. 限制条件:硬币总值不超过 n. 目标:求出组合种数. 令 dp[ i ][ j ] == x 表示用前 i 种硬币组合价值为 j 的钱共 x 种 ...
随机推荐
- JS编码三种方法的区别:escape、encodeURI和encodeURIComponent
1.escape和它们不是同一类 简单来说,escape是对字符串(string)进行编码(而另外两种是对URL),作用是让它们在所有电脑上可读.编码之后的效果是%XX或者%uXXXX这种形式.其中 ...
- 配置php扩展memcache
配置php扩展memcache 环境说明: 系统版本 CentOS 6.9 x86_64 软件版本 nginx-1.12.2 php-5.5.38 ...
- cmd.exe启动参数说明
启动命令解释程序 Cmd.exe 的新范例.如果在不含参数的情况下使用,cmd 将显示操作系统的版本和版权信息. 语法 cmd [{/c | /k}] [/s] [/q] [/d] [{/a | /u ...
- Linux中MySQL数据库max_allowed_packet的调整
在MySQL数据库里某表有一个blob字段,当上传文件超过1M的时候出现下面的错误: PreparedStatementCallback; SQL [insert into uos.docfile(r ...
- Roboware 下打包成so 文件并引用
一.生成.so文件 在ros中编译.so文件,如同在vs中编译C++版的dll文件.具体步骤如下: 步骤1: 首先建立.h文件和一个.cpp文件(该.cpp文件就是此次封装的内容) 步骤2: ...
- Servlet的API(一)
Servlet的API有很多,这里只谈谈两个Servlet对象:ServletConfig对象和ServletContext对象. 1. ServletConfig对象 在Servlet的配置文件中, ...
- Ffmpeg音频转码 卡顿(MP2转AAC)
最好经手一个小的功能将mp2实时流转成AAC并发布成rtmp音频流,本身不是很难的一个需求, 一个晚上就能将功能开发好.功能开发完毕后,找来一音频文件利用Ffmpeg命令将音视频文件推成 实时udp格 ...
- wcf 入门示例
刚开始学习wcf,根据官方网站的说明写下的代码 第一步: 建立一个类库项目GettingStartedLib,首先添加wcf引用System.ServiceModel; 添加接口ICalculator ...
- java之UDP(datagramsocket,datagramPacket)实例
import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import ...
- docker 让容器执行命令 与 进入容器交互
直接执行命令docker exec mynginx cat /etc/nginx/nginx.conf 进入容器交互docker exec -it 80nginx /bin/bash