zoukankan      html  css  js  c++  java
  • 【P1915】[usaco09 dec gold]电视游戏问题

    在百度上搜到了nzx学长的题解orz

    原题:

    农夫约翰的奶牛们游戏成瘾!本来FJ是想要按照陶叫兽的做法拿她们去电击戒瘾的,可是后来他发现奶牛们玩游戏之后比原先产更多的奶。很明显,这是因为满足的牛会产更多的奶。

    但是,奶牛们在哪个才是最好的游戏平台这个问题上产生了巨大的分歧。一只奶牛想要买一台Xbox 360来跑《光晕3》;另外一只奶牛想要一台任天堂Wii来跑《任天堂明星大乱斗X》;
    第三只奶牛想要在PlayStation 3上面玩《潜龙谍影4》,顺便还能看某些高画质的日本电
    影(呵呵)。FJ想要在给定的预算内购入一些游戏平台和一些游戏,使他的奶牛们生产最多的奶牛以养育最多的孩子。FJ研究了N(1 <= N <= 50)种游戏平台,每一种游戏平台的价格是P_i(1 <= P_i <= 1000),并且每一种游戏平台有G_i(1 <= G_i <= 10)个只能在这种平台上运行的游戏。很明显,奶牛必须先买进一种游戏平台,才能买进在这种游戏平台上运行的游戏。每一个游戏有一个游戏的价格GP_i(1 <= GP_j 价格 <= 100)并且有一个产出值PV_j(1 <= PV_j <= 1000000),表示一只牛在玩这个游戏之后会产出多少牛奶。最后,农夫约翰的预算为V(1 <= V <= 100000),即他最多可以花费的金钱。请帮助他确定应该买什么游戏平台和游戏,使得他能够获得的产出值的和最大。

    恩看上去是有依赖的背包问题,然而用每组依赖搞01包最优质看做v个物品再高分组背包的方法会T得很惨

    于是就可以在每组依赖关系开始的时候预处理一下:

    for(int j=a[i];j<=v;j++)  f[j]=F[j-a[i]];

    将F的值转移到f上,注意被依赖的物品的重量

    然后再搞分组背包,最后将f的最大值转移到F上

    这个题值得再好好看看

    代码:

     1 //3_108_120_116
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cmath>
     7 using namespace std;
     8 int read(){int z=0,mark=1;  char ch=getchar();
     9     while(ch<'0'||ch>'9'){if(ch=='-')mark=-1;  ch=getchar();}
    10     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
    11     return z*mark;
    12 }
    13 int n,v,a[110],bcost[110][110],bvalue[110][110],toub[110];
    14 int f[110000],F[110000];
    15 int maxx=0;
    16 int main(){//freopen("ddd.in","r",stdin);
    17     memset(f,0,sizeof(f));
    18     memset(F,0,sizeof(F));
    19     cin>>n>>v;
    20     for(int i=1;i<=n;i++){
    21         a[i]=read(),toub[i]=read();
    22         for(int j=1;j<=toub[i];j++)
    23             bcost[i][j]=read(),bvalue[i][j]=read();
    24     }
    25     for(int i=1;i<=n;i++){
    26         for(int j=a[i];j<=v;j++)  f[j]=F[j-a[i]];
    27         for(int j=1;j<=toub[i];j++)
    28             for(int k=v;k>=bcost[i][j]+a[i];k--)
    29                 f[k]=max(f[k],f[k-bcost[i][j]]+bvalue[i][j]);
    30         for(int j=a[i];j<=v;j++)  F[j]=max(F[j],f[j]),maxx=max(maxx,F[j]);
    31     }
    32     cout<<maxx<<endl;
    33     return 0;
    34 }
    View Code
  • 相关阅读:
    linux常见错误1 -> E: 无法获得锁 /var/lib/apt/lists/lock open
    std::ostringstream用法浅析
    (译)C++11中的Move语义和右值引用
    C++11学习笔记(1) Rangebased for loop
    (转)Linux 下压缩与解压.zip和.rar及.7z文件
    (转)linux 查看当前用户及用户所属组别
    ubuntu 源码编译安装cmake2.8.10.2
    开始自学H5前端第一天
    自学H5第二天
    顶部滚动菜单栏
  • 原文地址:https://www.cnblogs.com/JSL2018/p/6070044.html
Copyright © 2011-2022 走看看