[USACO14DEC]后卫马克Guard Mark

题目描述

FJ将飞盘抛向身高为H(1 <= H <= 1,000,000,000)的Mark,但是Mark

被N(2 <= N <= 20)头牛包围。牛们可以叠成一个牛塔,如果叠好后的高度大于或者等于Mark的高度,那牛们将抢到飞盘。

每头牛都一个身高,体重和耐力值三个指标。耐力指的是一头牛最大能承受的叠在他上方的牛的重量和。请计算牛们是否能够抢到飞盘。若是可以,请计算牛塔的最大稳定强度,稳定强度是指,在每头牛的耐力都可以承受的前提下,还能够在牛塔最上方添加的最大重量。

输入输出样例

输入样例#1:
4 10 
9 4 1 
3 3 5 
5 5 10 
4 4 5 
输出样例#1:
2 

f[i]表示集合i的奶牛最大的剩余耐力值。

f[i|j]=max(min(f[i]-w[j],w[j])),i&(1<<j-1)=0

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 int n,H,s[(1<<21)-1],f[(1<<21)-1],p[21],h[21],t[21],w[21],ans;
 7 int main()
 8 {int i,j;
 9     cin>>n>>H;
10      for (i=1;i<=n;i++)
11      {
12          scanf("%d%d%d",&h[i],&w[i],&t[i]);
13          s[1<<i-1]=h[i];
14          f[1<<i-1]=t[i];
15          p[i]=1<<i-1;
16      }
17      ans=-1;
18     for (i=1;i<=(1<<n)-1;i++)
19      {
20           for (j=1;j<=n;j++)
21            if ((i&p[j])==0)
22             {
23                 int x=i|p[j];
24                  f[x]=max(f[x],min(f[i]-w[j],t[j]));
25                   s[x]=s[i]+h[j];
26                    if (s[x]>=H&&f[x]>ans&&f[x]>0)
27                     ans=f[x];
28             }
29      }
30       if (ans!=-1)
31        cout<<ans;
32        else cout<<"Mark is too tall"; 
33 }

 

 

 

posted @ 2017-08-15 15:52  Z-Y-Y-S  阅读(279)  评论(0编辑  收藏  举报