GYM 101550 && CSUOJ 2017 Highest Tower 思维 模型转换

Description

Oni loved to build tall towers of blocks. Her parents were not as amused though. They were on the verge of going crazy over that annoying loud noise when- ever a tower fell to the ground, not to mention having to pick up blocks from the floor all the time. Oni’s mother one day had an idea. Instead of building the tower out of physical blocks, why couldn’t Oni construct a picture of a tower using two-dimensional rectangles that she montaged on a board on the wall?

Oni’s mother cut out rectangles of various sizes and colors, drew a horizontal line representing the ground at the bottom of the board, and explained the rules of the game to Oni: every rectangle must be placed immediately above another rectangle or the ground line. For every rectangle you can choose which of its two orientations to use. I.e., if a rectangle has sides of length s and t, you can either have a side of length s horizontally or a side of length t horizontally. You may place exactly one rectangle immediately above another one if its horizontal side is strictly smaller than the horizontal side of the rectangle beneath. Exactly one rectangle must be placed on the ground line. Now try to build as tall a tower as possible!

Oni’s mother took extra care to make sure that it was indeed possible to use all rectangles in a tower in order not to discourage Oni. But of course Oni quickly lost interest anyway and returned to her physical blocks. After all, what is the point of building a tower if you cannot feel the suspense before the inevitable collapse? Her father on the other hand got interested by his wife’s puzzle as he realized this is not a kids’ game.
Input

The first line of input contains an integer n(1≤n≤250000)
, the number of rectangles. Then follow n lines, each containing two integers s and t ( 1≤s≤t≤109

nm), the dimensions of a rectangle. You may safely assume that there is a way to build a tower using all n rectangles.
Output

Output a single line containing the height in nm of the tallest possible tower using all the rectangles while having the horizontal side lengths strictly decreasing from bottom to top.
Sample Input

3
50000 160000
50000 100000
50000 100000

Sample Output

200000

题意 给出n个方块 选取其中一些 堆叠在一起 要求宽严格递减 求最高能堆多高。题目保证有一种方法能使所有方块堆叠在一起。
解题思路:
没想出来,看题解也看了好久才理解。太菜了。
转化成图论题来写, 宽和高为边,每个方块就代表一条边。
题目要求方块宽严格递减 其实就是每种长度只能出现一次。
那么转化到图里 就是每个点只能被访问一次。
题目保证有一种方法能使所有方块堆叠在一起。 转化到图中 就是每个连通块最多只会出现一个环
接下来 https://blog.csdn.net/V5ZSQ/article/details/79337446 就说的很清楚了。。。。
还是太菜了 这种脑洞我根本想不到。。。。。。。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<map>
#define LL long long
using namespace std;
const int MAX=1e5*5+10;
int val[MAX];
int len[MAX];
bool vis[MAX];
map<int,int> M;
vector<int> V[MAX];
long long ans=0;
int e;
int num;
int maxs=-1;
void dfs(int u) {
    if(vis[u]) return;
    vis[u]=1;
    num++;
    e+=V[u].size();
    maxs=max(maxs,val[u]);
    ans+=(LL)val[u]*(V[u].size()-1);
    for(int i=0;i<V[u].size();i++){
        dfs(V[u][i]);
    }
}
int main() {
    int n;
    scanf("%d",&n);
    int tot=1;
    int u,v;
    for(int i=0; i<n; i++) {
        scanf("%d %d",&u,&v);
        if(!M[u]) {
            M[u]=tot;
            tot++;
        }
        if(!M[v]) {
            M[v]=tot;
            tot++;
        }
        V[M[v]].push_back(M[u]);
        V[M[u]].push_back(M[v]);
        val[M[v]]=v;
        val[M[u]]=u;
    }
    for(int i=1; i<tot; i++) {
        e=0;
        maxs=-1;
        num=0;
        if(!vis[i]){
            dfs(i);
            if(e/2<num) ans+=maxs;
        }
    }
    cout<<ans<<endl;
}

猜你喜欢

转载自blog.csdn.net/lifelikes/article/details/79821853
今日推荐