zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    信息安全算法
    另类装载问题
    分治法快速排序
    动态规划最长公共子序列
    java网络编程1
    Jndi和会话bean
    EJB初探
    JSF初探
    简单计算器
    关于坐火车
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7617099.html
Copyright © 2011-2022 走看看