[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 }