zoukankan      html  css  js  c++  java
  • Gym 101081K Pope's work

    题目链接:Gym - 101081K

    题意:给n个箱子,每个箱子有一个重量W和一个承重R,表示它上面能放最多R-W的重量。问最多能把多少箱子堆到一堆。

    思路:发现在一堆箱子里,两个箱子交换位置,对其他所有箱子没有影响。

    所以我们先构造偏序关系,考虑两个箱子i和j,假设Ri<Rj。

    那么我们发现假如Ri >= Wi + Wj,则Rj >= Wi + Wj。换言之,假如i上面可以放j,则j上面一定可以放j。但反之不一定成立。

    所以可以认为i<=j,按照这种偏序关系排序。

    按这种关系排序的好处在于,对于某个排在i后面的箱子j,假如我们想把j放在i上面,则这种情况显然不如把i放在j上面的情况好。

    换言之,对于每个箱子,我们只需要考虑排在它前面的箱子即可。

    接下来,用d[i][j]表示用前i个箱子堆j个箱子的最小重量。d[i][j]为INF时表示用前i个箱子不能堆j个箱子。

    那么可以得到转移方程

    最终答案为使d[n][i]不为INF的最大的i。

    代码如下:

     1 #include"cstdio"
     2 #include"iostream"
     3 #include"cstring"
     4 #include"algorithm"
     5 #include"cstdlib"
     6 #include"vector"
     7 #include"set"
     8 #include"map"
     9 #include"cmath"
    10 using namespace std;
    11 typedef long long LL;
    12 const LL MAXN=1010;
    13 const LL MOD=1000000000+7;
    14 const LL INF=0x3f3f3f3f;
    15 
    16 struct Box
    17 {
    18     int w,r;
    19     bool operator < (const Box x)
    20     {
    21         return r<x.r;
    22     }
    23 };
    24 Box s[MAXN];
    25 int d[MAXN][MAXN];
    26 int main()
    27 {
    28 #ifdef LOCAL
    29     freopen("in.txt","r",stdin);
    30     // freopen("out.txt","w",stdout);
    31 #endif
    32     int t;
    33     scanf("%d",&t);
    34     for(int tt=1;tt<=t;tt++)
    35     {
    36         int n;
    37         scanf("%d",&n);
    38         for(int i=1;i<=n;i++)
    39             scanf("%d%d",&s[i].w,&s[i].r);
    40         sort(s+1,s+1+n);
    41         memset(d,INF,sizeof(d));
    42         for(int i=0;i<=n;i++)
    43             d[i][0]=0;
    44         for(int i=1;i<=n;i++)
    45             for(int j=1;j<=i;j++)
    46             {
    47                 d[i][j]=d[i-1][j];
    48                 if(d[i-1][j-1]+s[i].w <= s[i].r && d[i-1][j-1]+s[i].w < d[i][j])
    49                     d[i][j]=d[i-1][j-1]+s[i].w;
    50             }
    51         for(int i=n;i>=0;i--)
    52             if(d[n][i]<INF)
    53             {
    54                 printf("%d
    ",i);
    55                 break;
    56             }
    57     }
    58     return 0;
    59 }
  • 相关阅读:
    test
    dd 命令 sd卡系统迁移
    关于庖丁分词
    Linux source命令
    Linux系统查看系统是32位还是64位方法总结 in 创新实训
    总结这两天连续干掉的bug In 创新实训 智能自然语言交流系
    穷举法应用——搬砖块
    判断素数类问题汇总
    统计计算学生成绩类问题汇总
    C语言简明数据类型指南
  • 原文地址:https://www.cnblogs.com/zarth/p/6757472.html
Copyright © 2011-2022 走看看