bzoj2021[Usaco2010 Jan]Cheese Towers*

bzoj2021[Usaco2010 Jan]Cheese Towers

题意:

John要建一个奶酪塔,高度最大为T。他有N种奶酪,每种无限个,第i种高度为Hi(一定是5的倍数),价值为Vi。一块高度>=K的奶酪被称为大奶酪,一个奶酪如果在它上方有大奶酪(多块只算一次),它的高度就会变成原来的4/5。求最大价值。n≤100,t≤1000

题解:

可以枚举放哪个≥k的奶酪放在顶,其它奶酪高度变为4/5,做个完全背包。最后再算一个没有≥k的奶酪放在顶的最大价值,比较一下。注意被放在顶的奶酪可以再选,因为是每种奶酪无限个。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define inc(i,j,k) for(int i=j;i<=k;i++)
 5 #define maxn 110
 6 #define INF 0x3fffffff
 7 using namespace std;
 8 
 9 struct nd{int h,v;}nds[maxn];
10 int f[2][maxn*10],n,t,k,x,y,ans;
11 inline int read(){
12     char ch=getchar(); int f=1,x=0;
13     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
14     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
15     return f*x;
16 }
17 int main(){
18     n=read(); t=read(); k=read(); inc(i,1,n)nds[i].v=read(),nds[i].h=read();
19     inc(i,1,n)if(nds[i].h>=k&&t>=nds[i].h){
20         x=0; y=1; memset(f,0,sizeof(f)); t-=nds[i].h;
21         for(int j=n;j>=1;j--){
22             for(int l=t;l>=0;l--){
23                 if(l+nds[j].h/5*4>t)f[y][l]=f[x][l];else f[y][l]=max(f[y][l+nds[j].h/5*4]+nds[j].v,f[x][l]);
24             }
25             swap(x,y);
26         }
27         ans=max(ans,f[x][0]+nds[i].v); t+=nds[i].h;
28     }
29     x=0; y=1; memset(f,0,sizeof(f));
30     for(int i=n;i>=1;i--)if(nds[i].h<k){
31         f[y][t]=0;
32         for(int j=t;j>=0;j--){
33             if(j+nds[i].h>t)f[y][j]=f[x][j];else f[y][j]=max(f[y][j+nds[i].h]+nds[i].v,f[x][j]);
34         }
35         swap(x,y);
36     }
37     ans=max(ans,f[x][0]); printf("%d",ans); return 0;
38     return 0;
39 }

 

20160828

转载于:https://www.cnblogs.com/YuanZiming/p/5838013.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值