• [LOJ500]ZQC的拼图


    题目大意:
      给你一个m*m的格子,让你往里面放给定的直角三角形,直角顶点必须放在右上角且不能翻转,但是可以把所有给定的三角形放大一个整数倍k,问至少放大几倍能使格子的左下角和右上角连起来?(可以超出边界)

    思路:
      二分答案+DP。
      二分一个解m,然后用DP来检验。
      用f[i][j]表示放到第i个三角形,横坐标到达j时纵坐标的最大值。
      转移方程为f[i][j]=max{f[i-1][k]+(m-(j-k)*x[i])/y[i]}。
      最后判断一下f[n][m]>=m即可。

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<algorithm>
     4 inline int getint() {
     5     register char ch;
     6     while(!isdigit(ch=getchar()));
     7     register int x=ch^'0';
     8     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
     9     return x;
    10 }
    11 const int _inf=-0x80000000;
    12 const int N=100,M=101;
    13 std::pair<int,int> t[N];
    14 int n,m;
    15 int f[2][M];
    16 inline bool check(const int &k) {
    17     f[0][0]=0;std::fill(&f[0][1],&f[0][m+1],_inf);
    18     f[1][0]=0;std::fill(&f[1][1],&f[1][m+1],_inf);
    19     for(register int i=0;i<n;i++) {
    20         for(register int j=0;j<=m&&j<=k/t[i].first;j++) {
    21             const int tmp=(k-j*t[i].first)/t[i].second;
    22             for(register int l=m-j;l>=0;l--) {
    23                 f[i&1][j+l]=std::max(f[i&1][j+l],f[!(i&1)][l]+tmp);
    24             }
    25         }
    26     }
    27     return f[!(n&1)][m]>=m;
    28 }
    29 int main() {
    30     n=getint(),m=getint();
    31     for(register int i=0;i<n;i++) {
    32         t[i]=std::make_pair(getint(),getint());
    33     }
    34     int l=0,r=1e8;
    35     while(l<r) {
    36         const int mid=(l+r)>>1;
    37         if(check(mid)) {
    38             r=mid;
    39         } else {
    40             l=mid+1;
    41         }
    42     }
    43     printf("%d
    ",(l+r)>>1);
    44     return 0;
    45 } 
  • 相关阅读:
    __slots__魔法,减少实例属性消耗的内存
    在函数中最好不要用可变类型当参数
    Python的容器模块
    实例和类变量以及类的魔术方法
    推导式
    Python内置函数
    常用的git操作(持续更新)
    h开头的
    e开头的
    如何迁移测试的MAGENTO到正式运行的MAGENTO
  • 原文地址:https://www.cnblogs.com/skylee03/p/7777343.html
Copyright © 2020-2023  润新知