GCD(ZYYS)
【问题描述】
在山的那边、海的那边有 n 个小矮人,他们生存的意义就是要保护他们的精
神领袖——GCD。有一天,他们收到了一封恐吓信,说要在一个遥远的地方用维
纳斯之箭射击 GCD,让他变成一根面条,n 个小矮人当然要保护 GCD,GCD 实在
是太高了,于是矮人们决定搭成一个不低于 GCD 的矮人塔,可他们智商很低,
于是就找到了你。
每个小矮人都有三个指数:h,w,s,分别代表身高,体重与承受力,每一个小
矮人上方所搭的矮人的体重之和不能超过他的承受力。
小矮人想问你他们能不能搭成一个符合要求的塔,如果能的话,他们还想问
你搭成的塔的最大的稳定性(塔的稳定性指的是还能在塔上方最多加的重量)。
【输入格式】
从 b.in 读入数据
两个正整数 n,H,H 表示 GCD 的身高。
接下来 n 行,每行三个正整数 h, w, s,意义如题中所述。
【输出格式】
输出到文件 b.out 中
如果不能,则输出 GCD is too tall
否则,输出一个正整数,表示塔的最大稳定性。
【样例输入 1】
4 10
941
335
5 5 10
445
【样例输出 1】
2
【样例解释】
从底向上分别放 3 号,4 号,二号
【样例输入 2】
4 100
941
335
5 5 10
445
【样例输出 2】
GCD is too tall
【数据规模和约定】对于 20%的数据,n<=10
对于 40%的数据,n<=20
对于 60%的数据,n<=25
对于 70%的数据,n<=30
对于 100%的数据,n<=50,H<=2147483647;h,w,s <= 10^9
其中有数据满足:
H <= 30000
H <= 40000
H <= 80000
H <= 130000
H <= 260000
保证数据随机生成~
我们考虑要选的小矮人 i,j,比较谁放在下面更优,当然是通过放了之后的
稳定值来比较,贪心地想,稳定值越大当然越好。
i 放在下面的稳定值为: s[i] - w[j];
所以,i 比 j 优的条件为: s[i] - w[j] > s[j] - w[i];
即: s[i] + w[i] > s[j] + w[j];
所以,我们开始把小矮人按 s + w 排序,对于选出来的小矮人,就不用枚举顺
序了
不过当然要加
上最优性剪枝(可行性剪枝好像没什么效果)。复杂度:O(???)
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 typedef long long lol; 7 struct Zt 8 { 9 lol h,w,s; 10 }a[101]; 11 lol n,h,ans=-1,sumh[101],sumw[101]; 12 bool cmp(Zt a,Zt b) 13 { 14 return (min(a.s-b.w,b.s)>min(b.s-a.w,a.s)); 15 } 16 void dfs(int x,lol H,lol P) 17 { 18 if (H>=h) 19 { 20 if (P>ans) ans=P; 21 return; 22 } 23 if (x>n) return; 24 if (ans>=P) return; 25 if (H+sumh[n]-sumh[x-1]<h) return; 26 if (a[x].w<=P) 27 dfs(x+1,H+a[x].h,min(a[x].s,P-a[x].w)); 28 if (P) 29 dfs(x+1,H,P); 30 } 31 int main() 32 {int i; 33 cin>>n>>h; 34 for (i=1;i<=n;i++) 35 { 36 scanf("%lld%lld%lld",&a[i].h,&a[i].w,&a[i].s); 37 } 38 sort(a+1,a+n+1,cmp); 39 for (i=1;i<=n;i++) 40 { 41 sumh[i]=sumh[i-1]+a[i].h; 42 sumw[i]=sumw[i-1]+a[i].w; 43 } 44 dfs(1,0,2e9); 45 if (ans==-1) cout<<"GCD is too tall"; 46 else 47 cout<<ans; 48 }