限量供应

Time limit per test: 4.0 seconds

Time limit all tests: 4.0 seconds

Memory limit: 256 megabytes

华东师大的食堂常常有许多很奇怪的菜,比方说:玉米炒葡萄、玉米炒草莓、玉米炒香蕉……所以很多同学,包括你,去食堂吃东西,是只吃菜,不吃饭的。

但这些菜都是限量供应的:如果你今天点了某一道菜,那么接下来 r 天(不包括今天)你都不能再点这道菜了。当然,同一道菜在同一天内点两份也是不可以的。此外,因为你是从来不吃饭的,所以为了保证能量充足,你每天吃的所有菜的卡路里总和必须大于等于 C。

在本学期的 m 天中,你每天都要在食堂吃。你现在既想吃得多,又不能吃得太多,所以你提出了以下两个要求:

  1. 在不违背上述条件的前提下,吃的菜的数目(不是种类数)应尽可能多;

  2. 在不违背 1 的前提下,吃的所有菜的卡路里总和应尽可能小。

Input

第一行是一个整数 T (1≤T≤100),表示测试数据组数。

接下来是 T 组测试数据,每组数据两行。

第一行四个整数 n,m,r,C (1≤n≤12,1≤m≤1000,1≤r≤20,1≤C≤105)。其中 n 表示菜的种数,其余变量含义如题中描述。

第二行 n 个整数:c1,c2,…,cn (1≤ci≤105)。

Output

对于每组数据,输出 Case x: y z。x 表示从 1 开始的测试数据编号,y 和 z 分别表示菜的数目和卡路里总和。如果没有满足要求的方案,y 和 z 是 0 0

Examples

Input
  1. 2
  2. 7 9 3 3
  3. 3 2 2 2 2 3 3
  4. 7 5 3 3
  5. 3 2 2 2 2 3 3
Output
  1. Case 1: 18 42
  2. Case 2: 11 25

Source

2017 华东师范大学校赛

  1. /**
  2. 题目:EOJ Problem #3249
  3. 链接:http://acm.ecnu.edu.cn/problem/3249/
  4. 题意:
  5. 华东师大的食堂常常有许多很奇怪的菜,比方说:玉米炒葡萄、玉米炒草莓、玉米炒香蕉……
  6. 所以很多同学,包括你,去食堂吃东西,是只吃菜,不吃饭的。
  7. 但这些菜都是限量供应的:如果你今天点了某一道菜,那么接下来 r 天(不包括今天)你都不能再点这道菜了。
  8. 当然,同一道菜在同一天内点两份也是不可以的。此外,因为你是从来不吃饭的,所以为了保证能量充足,
  9. 你每天吃的所有菜的卡路里总和必须大于等于 C。
  10. 在本学期的 m 天中,你每天都要在食堂吃。你现在既想吃得多,又不能吃得太多,
  11. 所以你提出了以下两个要求:
  12.  
  13. 1,在不违背上述条件的前提下,吃的菜的数目(不是种类数)应尽可能多;
  14.  
  15. 2,在不违背 1 的前提下,吃的所有菜的卡路里总和应尽可能小。
  16. ,
  17. 思路:
  18.  
  19. 预处理s表示满足>=C的菜的集合。
  20.  
  21. 假设总共有n个s满足条件。
  22.  
  23. 那么将n个s。选出来。
  24.  
  25. 排列一行,m个。
  26.  
  27. 保证区间长度r+1范围内的s不能有相同的菜。满足的序列中,取菜的数目最多,然后考虑总卡路里最小。
  28.  
  29. 如果能够找到这样的r+1个s。那么此后都这样循环便是最优。
  30.  
  31. 20*4096 = 81920
  32.  
  33. dp[i][s]表示前i天选了s集合的菜是否成立。
  34.  
  35. dp[i][s] = dp[i-1][s'];
  36.  
  37. dp[0][0] = 1;
  38.  
  39. 如果m<r+1; 那么直接就可以遍历dp[m][s]中的s为真时候的s的菜数目num以及花费ans。
  40. 如果m>r+1; 遍历dp[r+1][s]中的s为真时候的s的菜数目num以及卡路里花费ans就可以知道m/(r+1)个周期结果为num*(m/(r+1)), ans*(m/(r+1));
  41. 然后还会多余m%(r+1),知道了r+1的状态s,就可以反向递推获得dp[m%(r+1)][s0]可以得到的s0(因为连续r+1天不能存在相同的,
  42. 所以受到前r+1的状态s的影响,通过反向递推解决).然后计算s0的结果加上那m/(r+1)个周期结果。
  43. 注意:r+1天算出的最优的s,不能保证通过这个s反向递推的s0是最优的。我的处理方法是:暴力所有可能的s,然后对每个s反向递推s0.
  44. 比较所有的结果中最优的。
  45.  
  46. */
  47.  
  48. #include <iostream>
  49. #include <cstdio>
  50. #include <cstring>
  51. #include <cmath>
  52. #include <algorithm>
  53. #include <cstdlib>
  54. #include <time.h>
  55. using namespace std;
  56. typedef long long LL;
  57. const int mod=1e9+;
  58. const int maxn=1e6+;
  59. int T, n, m, r, C;
  60. LL cost[<<];
  61. LL c[];
  62. int dp[][<<];
  63. int digit[<<];
  64. LL num = , ans = , num1 = , ans1 = ;
  65. void init(int n)///ok
  66. {
  67. int len = <<n;
  68. for(int i = ; i < len; i++){
  69. cost[i] = ;
  70. digit[i] = ;
  71. for(int j = ; j < n; j++){
  72. if(i&(<<j)){
  73. cost[i]+=c[j];
  74. digit[i]++;
  75. }
  76. }
  77. }
  78. }
  79. LL num2, ans2;
  80. void dfs(int m,int i,int s)
  81. {
  82. if(i==m){
  83. int cnt = digit[s];
  84. if(cnt>num2){
  85. num2 = cnt; ans2 = cost[s];
  86. }else
  87. {
  88. if(cnt==num2){
  89. if(cost[s]<ans2){
  90. ans2 = cost[s];
  91. }
  92. }
  93. }
  94. return ;
  95. }
  96. for(int s0 = s; s0; s0 = (s0-)&s){
  97. if(cost[s0]<C) continue;///比赛的时候,这道题!!!我少了这行代码。。。唉。dp[i-1][s-s0]如果为真,未必是当前这个状态到来的,
  98. ///必须加一个判断条件,判断是否可以由s到s-s0;
  99. if(dp[i-][s-s0]){
  100. dfs(m,i-,s-s0);
  101. }
  102. }
  103.  
  104. }
  105. int main()
  106. {
  107. cin>>T;
  108. int cas = ;
  109. while(T--)
  110. {
  111. scanf("%d%d%d%d",&n,&m,&r,&C);
  112. for(int i = ; i < n; i++) scanf("%lld",&c[i]);
  113. init(n);
  114. memset(dp, , sizeof dp);
  115. dp[][] = ;
  116. int len = <<n;
  117. int mis = min(r+,m);
  118. for(int i = ; i <= mis; i++){
  119. for(int s = ; s < len; s++){
  120. if(cost[s]<C) continue;
  121. for(int s0 = s; s0; s0 = (s0-)&s){
  122. if(cost[s0]<C) continue;
  123. dp[i][s] |= dp[i-][s-s0];
  124. }
  125. }
  126. }
  127.  
  128. num = , ans = ;
  129. if(r+>=m){
  130. for(int s = ; s < len; s++){
  131. if(dp[m][s]){
  132. int cnt = digit[s];
  133. if(cnt>num){
  134. num = cnt; ans = cost[s];
  135. }else
  136. {
  137. if(cnt==num){
  138. if(cost[s]<ans) ans = cost[s];
  139. }
  140. }
  141. }
  142. }
  143. }else
  144. {///m > r+1;
  145. for(int s = ; s < len; s++){
  146. if(dp[r+][s]){
  147. ans1 = cost[s];
  148. num1 = digit[s];
  149. num1 = m/(r+)*num1;
  150. ans1 = m/(r+)*ans1;
  151. num2 = ans2 = ;
  152. if(m%(r+)!=){
  153. dfs(m%(r+),r+,s);
  154. }
  155. num1 += num2;
  156. ans1 += ans2;
  157. if(num1>num){
  158. num = num1; ans = ans1;
  159. }else
  160. {
  161. if(num1==num&&ans1<ans){
  162. ans = ans1;
  163. }
  164. }
  165. }
  166. }
  167. }
  168. printf("Case %d: %lld %lld\n",cas++,num,ans);
  169. }
  170. return ;
  171. }

EOJ Problem #3249 状态压缩+循环周期+反向递推的更多相关文章

  1. HDU 1757 A Simple Math Problem 【矩阵经典7 构造矩阵递推式】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=1757 A Simple Math Problem Time Limit: 3000/1000 MS (J ...

  2. 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 M. Frequent Subsets Problem【状态压缩】

    2017 ACM-ICPC 亚洲区(南宁赛区)网络赛  M. Frequent Subsets Problem 题意:给定N和α还有M个U={1,2,3,...N}的子集,求子集X个数,X满足:X是U ...

  3. 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛:Frequent Subsets Problem (状态压缩)

    题目链接 题目翻译: 给出一个数n,和一个浮点数a,数n代表全集U = {1,2,...,n},然后给出 M个U的子集,如果一个集合B(是U的子集),M个集合中有至少M*a个集合包含B, 则B这个集合 ...

  4. poj1753 Flip Game —— 二进制压缩 + dfs / bfs or 递推

    题目链接:http://poj.org/problem?id=1753 Flip Game Time Limit: 1000MS   Memory Limit: 65536K Total Submis ...

  5. 【bzoj1076】[SCOI2008]奖励关 期望dp+状态压缩dp

    题目描述 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再 ...

  6. C语言 分支与循环 递推思想 穷举 流程的转移控制

    条件语句 开关控制语句(SWITCH语句) 象坐电梯一样,break是按的楼层,不加break则会一直执行下去. 上面程序有细节BUG,边界测试输入-5,105时由于整除会得到错误的结果. 解决方法: ...

  7. FZU-2218 Simple String Problem(状态压缩DP)

      原题地址: 题意: 给你一个串和两个整数n和k,n表示串的长度,k表示串只有前k个小写字母,问你两个不含相同元素的连续子串的长度的最大乘积. 思路: 状态压缩DP最多16位,第i位的状态表示第i位 ...

  8. 旅行商问题——状态压缩DP

    问题简介 有n个城市,每个城市间均有道路,一个推销员要从某个城市出发,到其余的n-1个城市一次且仅且一次,然后回到再回到出发点.问销售员应如何经过这些城市是他所走的路线最短? 用图论的语言描述就是:给 ...

  9. Escape(状态压缩+最大流,好题)

    Escape http://acm.hdu.edu.cn/showproblem.php?pid=3605 Time Limit: 4000/2000 MS (Java/Others)    Memo ...

随机推荐

  1. 【译】PHP中的Session及其一些安全措施

    有一点我们必须承认,大多数web应用程序都离不开session的使用.这篇文章将会结合php以及http协议来分析如何建立一个安全的会话管理机制.我们先简单的了解一些http的知识,从而理解该协议的无 ...

  2. [shell 编程] if [ $# -eq 0 ]该语句是什么含义?

    $0: shell或shell脚本的名字$*:以一对双引号给出参数列表$@:将各个参数分别加双引号返回$#:参数的个数$_:代表上一个命令的最后一个参数$$:代表所在命令的PID$!:代表最后执行的后 ...

  3. [Java基础] Java多线程-工具篇-BlockingQueue

    转载自: http://www.cnblogs.com/jackyuj/archive/2010/11/24/1886553.html 前言: 在新增的Concurrent包中,BlockingQue ...

  4. RabbitMQ,Apache的ActiveMQ,阿里RocketMQ,Kafka,ZeroMQ,MetaMQ,Redis也可实现消息队列,RabbitMQ的应用场景以及基本原理介绍,RabbitMQ基础知识详解,RabbitMQ布曙

    消息队列及常见消息队列介绍 2017-10-10 09:35操作系统/客户端/人脸识别 一.消息队列(MQ)概述 消息队列(Message Queue),是分布式系统中重要的组件,其通用的使用场景可以 ...

  5. 函数指针&指针函数

    https://blog.csdn.net/luoyayun361/article/details/80428882

  6. javascript快速入门9--引用类型

    引用类型通常叫做类(class),也就是说,遇到引用值,所处理的就是对象. 注意:从传统意义上来说,ECMAScript 并不真正具有类.事实上,除了说明不存在类,在 ECMA-262 中根本没有出现 ...

  7. solr6.6 solrJ索引富文本(word/pdf)文件

    1.文件配置 在core下面新建lib文件夹,存放相关的jar包,如图所示: 修改solrconfig.xml <lib dir="${solr.install.dir:../../. ...

  8. Ajax的原理和应用

    这篇文章中,我将从10个方面来对AJAX技术进行系统的讲解. 1.ajax技术的背景 不可否认,ajax技术的流行得益于google的大力推广,正是由于google earth.google sugg ...

  9. 字符串去重(hashSet)

    public static String deleteRepeat(String strn){          String s=strn;        String[] array = s.sp ...

  10. zStack学习笔记(原创,绝对不是抄的……)

    我之前写的文章都没写上面那句,但是这篇写了,主要是因为zStack文章抄袭太严重……故此声明 因为涉及到数据的双向交互问题,所以在这里我考虑使用协议栈来实现数据的收发.首先说下如何在Zstack中添加 ...