zoukankan      html  css  js  c++  java
  • vijosP1059 积木城堡

    vijosP1059 积木城堡

    链接:https://vijos.org/p/1059

    【思路】

       01背包。

       刚开始想麻烦了,想的是二分答案然后01背包判断是否可行,但是首先答案不满足单调性所以不能二分(这点以后做题之前一定要想清楚),其次如果从大到小枚举依次判定的话会TLE。

       不得不说自己真是笨。

       其实可以对每一组积木用一次01背包,用一个cnt记录满足该高度的城堡数目。然后从大到小检查如果为n输出即可。时间上是O(n^3)。

    【代码】

     1 #include<iostream>
     2 #include<cstring>
     3 #define FOR(a,b,c) for(int a=(b);a<(c);a++)
     4 using namespace std;
     5 
     6 const int maxn = 100+10;
     7 
     8 int h[maxn][maxn],sum[maxn];
     9 bool d[maxn*maxn];
    10 int cnt[maxn*maxn];
    11 int n;
    12 
    13 void dp(int tot,int* A) {
    14     int len=A[0];
    15     d[0]=true;
    16     FOR(i,1,len)
    17        for(int j=tot;j>=A[i];j--)
    18        {
    19           d[j] = d[j] || d[j-A[i]];
    20        }
    21     FOR(i,0,tot+1) cnt[i] += d[i];
    22 }
    23 
    24 int main() {
    25     ios::sync_with_stdio(false);
    26     cin>>n;
    27     int x,R=0;
    28     FOR(i,0,n) {
    29         h[i][0]=1;
    30         while(cin>>x && x!=-1) {
    31             h[i][h[i][0]++]=x;
    32             sum[i] += x;
    33         }
    34         R=max(R,sum[i]);
    35     }
    36 
    37     FOR(j,0,n) 
    38     {
    39        memset(d,0,sizeof(d));
    40        dp(sum[j],h[j]);
    41     }
    42     for(int i=R;i>=0;i--)
    43        if(cnt[i]>=n) {
    44               cout<<i<<"
    ";
    45               break;
    46        }
    47     return 0;
    48 }
  • 相关阅读:
    docker添加sudo权限
    服务器出口ip
    flask
    ACM-奇特的立方体
    ACM-牛喝水
    ACM-可乐兑换
    ACM-Work Assignment
    ACM-DFS Template
    ACM-Checker Challenge
    ACM-Divide Tree
  • 原文地址:https://www.cnblogs.com/lidaxin/p/4904612.html
Copyright © 2011-2022 走看看