题目链接http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=13

题目大意:说的是有三种不同的装备,分别是头盔,盔甲,战靴需要运输,每种装备拥有不同的重量,体积,以及防御能力.当三种装备按照一定的数量规定组合成套装时,套装可以发挥处更强的攻击能力.然后有n个运输车,每个车能够运送的重量和体积有限制,现在问如何给这个n个运输车分配运送任务(即每个运输队运多少头盔,多少盔甲,多少战靴) 可以获得总的防御值最大。

输入描述:第一行是运输车的数量n。接下来是第1行是每个头盔的重量w1、体积s1、防御能力d1;第2行是每个盔甲的重量w2、体积s2、防御能力d2;第3行是每个战靴的重量w3、体积s3、防御能力d3;第4行是每个c1头盔,c2个盔甲,c3个战靴组成的套装的防御能力d4。接下来的n行每行2个整数,分别表示每个运输车能承受的最大重量和体积。

Sample Input

3
1 1 3
5 6 10
2 1 2
1 1 1 50
1 1
5 6
2 1
0

Output for the Sample Input

Case 1: 50

分析:能把复杂度降下来的就可以称为DP。

法1:由于套装威力强,我们应该凑出尽量多的套装然后再单算剩余装备的防御力.因此在运输的头盔数,盔甲数一定时要使运输的战靴数尽可能地多。

1、G++下,至少在dp型数组中,用memset、和memcpy函数的效率不如用循环初始化、复制快
2、此题以dp[i][j]存储拿了 i 件头盔(a武器),j 件盔甲(b武器)时能拿的最大的战靴(c武器)的数量
3、最后一个状态(最后一个车到达)后,用compute函数计算分别拿了各种数
量的三种武器后,能达到的防御力,从中挑选最大的

 法2:网上很多人的思路都是设f[i][n1][n2]表示用前i量车子在运 n1件1武器和n2件2武器的条件下能运的第3种武器的最大数量。

  那么f[0][0][0]=0设函数num(i,j,k)表示第i量车子在运j个1武器和k个2武器后最多再能运k个3武器,则f[i][n1][n2]=f[i-1][n3][n4]+num(i,n1-n3,n2-n4)

  f[i]的值只于f[i-1]有关,那么可以用滚动数组来节省空间

  本以为是背包,牛们居然用枚举做出来了

法1代码如下:

  1. # include<stdio.h>
  2. # include<memory.h>
  3. # define MAXN
  4. int dp[MAXN][MAXN],dp2[MAXN][MAXN];
  5. int car[][]; //car[0][i]、car[1][i] 分别表示第i辆车的能承受的重量、体积
  6. int n; //车的数量
  7. int w1,w2,w3,s1,s2,s3,c1,c2,c3,d1,d2,d3,d4;
  8.  
  9. int min(int a,int b){
  10. return a<b ? a :b;
  11. }
  12.  
  13. int compute(int a,int b,int c){ //计算防御能力
  14. int minnum;
  15. minnum = min(min(a/c1,b/c2),c/c3);
  16. return (minnum * d4 + (a- minnum*c1)*d1 + (b- minnum*c2)*d2 + (c- minnum*c3)*d3);
  17. }
  18.  
  19. int main(){
  20. int i,j,k,cas=,x,y;
  21. int curr_a,curr_b; //分别表示所有车全部装头盔、全部装盔甲 的最大数量
  22. while(scanf("%d",&n)== && n){
  23. scanf("%d%d%d%d%d%d%d%d%d%d%d%d%d",
  24. &w1, &s1, &d1,
  25. &w2, &s2 ,&d2,
  26. &w3, &s3, &d3,
  27. &c1, &c2, &c3, &d4);
  28. for(i=;i<n;i++) scanf("%d%d",&car[][i],&car[][i]);
  29. for(i=; i<MAXN; i++)
  30. for(j=; j<MAXN; j++)
  31. dp[i][j] = dp2[i][j] = -;
  32. curr_a = curr_b = ;
  33. dp2[][] = ;
  34. k = ;
  35. while(k < n){
  36. for(i=; i<= curr_a; i++)
  37. for(j=; j<=curr_b; j++){
  38. dp[i][j] = dp2[i][j];
  39. dp2[i][j] = -;
  40. }
  41. int r_a =min(car[][k] / w1, car[][k] / s1); //该车能够装头盔数量的最大值
  42. for(i=; i<=r_a; i++)
  43. {
  44. int r_aw = car[][k] - i * w1; //装了头盔后剩下的总重量
  45. int r_as = car[][k] - i * s1; //装了头盔后剩下的总体积
  46. int r_b = min(r_aw / w2, r_as / s2); //该车剩下部分能够装盔甲数量的最大值
  47. for(j=; j<=r_b; j++)
  48. {
  49. int r_bw = r_aw - j * w2; //再装盔甲后剩下的总重量
  50. int r_bs = r_as - j * s2; //再装盔甲后剩下的总体积
  51. int r_c = min(r_bw / w3,r_bs/s3); //该车剩余部分最多能装战靴的数量
  52. for(x=; x<=curr_a; x++)
  53. for(y=; y<=curr_b; y++)
  54. if(dp[x][y] >= && dp[x][y] + r_c >dp2[x+i][y+j])
  55. dp2[x+i][y+j] = dp[x][y] +r_c;
  56. }
  57. }
  58. curr_a += min(car[][k] / w1, car[][k] / s1);
  59. curr_b += min(car[][k] / w2, car[][k] / s2);
  60. k++;
  61. }
  62. int ans =;
  63. for(i=; i<=curr_a; i++)
  64. for(j=; j<=curr_b; j++)
  65. if(dp2[i][j] != -){
  66. int temp = compute(i,j,dp2[i][j]);
  67. if(temp > ans) ans = temp;
  68. }
  69. if(cas>) puts("");
  70. printf("Case %d: %d\n", ++cas, ans);
  71. }
  72. return ;
  73. }

ZOJ 1013 Great Equipment(DP)的更多相关文章

  1. ZOJ 4027 Sequence Swapping(DP)题解

    题意:一串括号,每个括号代表一个值,当有相邻括号组成()时,可以交换他们两个并得到他们值的乘积,问你最大能得到多少 思路:DP题,注定想得掉头发. 显然一个左括号( 的最远交换距离由他右边的左括号的最 ...

  2. ZOJ 2625 Rearrange Them(DP)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1625 题目大意:将n个数重新排列,使得每个数的前一个数都不能和之前的 ...

  3. ZOJ 2745 01-K Code(DP)(转)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1745 题目大意:一个串由N个字符组成,每个字符是‘0’或者是‘1’, ...

  4. ZOJ 3211 Dream City(DP)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3374 题目大意:JAVAMAN 到梦幻城市旅游见到了黄金树,黄金树上 ...

  5. ZOJ 2702 Unrhymable Rhymes(DP)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1702 题目大意:给定有很多数字组成的诗,譬如 “AABB”, “AB ...

  6. LightOJ 1033 Generating Palindromes(dp)

    LightOJ 1033  Generating Palindromes(dp) 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid= ...

  7. lightOJ 1047 Neighbor House (DP)

    lightOJ 1047   Neighbor House (DP) 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87730# ...

  8. UVA11125 - Arrange Some Marbles(dp)

    UVA11125 - Arrange Some Marbles(dp) option=com_onlinejudge&Itemid=8&category=24&page=sho ...

  9. ZOJ 2477 Magic Cube(魔方)

    ZOJ 2477 Magic Cube(魔方) Time Limit: 2 Seconds      Memory Limit: 65536 KB This is a very popular gam ...

随机推荐

  1. Git提交引用和引用日志

    转载自:https://github.com/geeeeeeeeek/git-recipes/wiki/5.5-Git%E6%8F%90%E4%BA%A4%E5%BC%95%E7%94%A8%E5%9 ...

  2. string,vector和array(C++ Primer读书笔记)

    string string是标准库类型,使用时需要包涵头文件,使用using声明. include <string> using std::string; 1.定义和初始化 string ...

  3. 联通超级战舰W910 Root 后不能 上网 解决方案

    联通版的超级战舰w910root后不能上网,一下是root方法: 超级战舰W910 Root方法: 电脑上安装“刷机精灵”(http://www.shuame.com/ ),在手机“菜单”——“系统设 ...

  4. hibernate三级缓存介绍

    hibernate缓存机制:分为三种:1.一级缓存(session级别缓存,同一session中不会重复发出sql,默认会实现)2.二级缓存(跨session的缓存,不同session会从同一缓存中取 ...

  5. PTA 5-12 排序 (25分)

    给定NN个(长整型范围内的)整数,要求输出从小到大排序后的结果. 本题旨在测试各种不同的排序算法在各种数据情况下的表现.各组测试数据特点如下: 数据1:只有1个元素: 数据2:11个不相同的整数,测试 ...

  6. 非常实用的Android Studio快捷键

    One—打印Log 生成tag: logt 打印log: logm logd loge Two—代码提示 Ctrl + Alt + Space Three—代码移动 选中代码: Ctrl + w 向 ...

  7. SRM566 1000pts

    绍一的模拟赛题 [题意] 小Z养了$

  8. iOS开发 落地消息多的处理办法(仅供参考)

    1.首先要知道一点,你的消息储存是用数据库储存的! 看了一下微信和qq的消息处理,一般情况下第三方(亲加,容云,环信都会有本地的数据库)处理过的! 但是我发现,最近一个需求要求开发@"消息已 ...

  9. (翻译)什么是Java的永久代(PermGen)内存泄漏

    http://www.codelast.com/?p=7248 转载请注明出处:http://www.codelast.com/ 本文是我对这篇文章的翻译:What is a PermGen leak ...

  10. [Javascript] Create an Array concatAll method

    In addition to flat Arrays, programmers must often deal with nested Arrays. For example let's say we ...