POJ 2161 Chandelier(树状DP)

一、题意

首先是对题目的翻译。给出一个长长的字符串,这个字符串描述了一个吊灯。对于给字符串只有两种操作数——‘a‘为一个吊灯灯珠,将改灯珠入栈,一位阿拉伯数字K,代表一个环,将把该数字前面k位数都出栈并且穿成一个环,并将该环重新入栈(作为一个单元)。由此可以得到一颗神奇的树——每个节点的若干子节点呈现循环数组的关系。因而此处有对于同构的定义为:再该环上各个小串的相对位置不变。于是,要求一个新的字符串,能够成上述字符转的一个同构的树,在这个基础上求出最小的“最大栈空间”大小。

二、思路

首先设dp[i]为将第i个节点及其子树全部入栈的最小栈大小。对于其第一个入栈的子树,认为此时的最高栈高度为k,则dp[i]=main(dp[i],dp[tar]+i)。此时应当枚举起点并且找到使得值最小的起点。

(红书说是使用单调栈实现O(N)的求出这个值得具体大小,但是经过隔壁队YC大佬指点发现不是单调栈而是一个简单思路(复杂度O(n))对于每个起点的特定顺序,必然有,最大值为上一个的最大值-1,或者上一个的起点+m-1。于是这样就可以O(1)的找出每一组的最大值,直接对比就好)

//#include<bits/stdc++.h>
#include<vector>
#include<stack>
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
#define veci vector<int>
#define stai stack<int>

const long long MAXN=1e4+233;
veci G[MAXN];
stai ss;
char str[MAXN];
int length;
int dp[MAXN];
int pos[MAXN];

int deal(int now)
{
    int len=G[now].size();
    int maxx=dp[G[now][0]];
    for(int i=0;i<len;++i)
    {
        maxx=max(maxx,dp[G[now][i]]+i);
    }
    int ans=maxx;
    for(int i=1;i<len;++i)
    {
        maxx=max(maxx-1,dp[G[now][i-1]]+len-1);
        if(ans>maxx)
        {
            pos[now]=i;
            ans=maxx;
        }
    }
    return ans;
}

void dfs(int now)
{
    int len=G[now].size();
    if(len==0)
    {
        dp[now]=1;return ;
    }
    for(int i=0;i<len;++i)
    {
        int tar=G[now][i];
        dfs(tar);
    }
    dp[now]=deal(now);
}

void show(int now)
{
    int len=G[now].size();
    if(len==0)
    {
        cout<<"a";return ;
    }
    for(int i=0;i<len;++i)
    {
        int pp=pos[now]+i;
        pp%=len;
        int tar=G[now][pp];
        show(tar);
    }
    cout<<G[now].size();
}

void init()
{
//    gets(str+1);
    length=strlen(str+1);
    memset(dp,0,sizeof(dp));
    memset(pos,0,sizeof(pos));
    int ll=0;
    for(int i=1;i<=length;++i)
    {    

        G[i].clear();
            ll=max(ll,(int)ss.size());
        if(str[i]!=‘a‘)
        {
            int len=str[i]-‘0‘;
            stai s2;
            for(int j=0;j<len;++j)
            {
//                int tar=ss.top();
                s2.push(ss.top());
                ss.pop();
//                G[i].push_front(tar);
//                G[i].push_back(tar);
            }
            while(!s2.empty())
            {
                G[i].push_back(s2.top());
                s2.pop();
            }

        }    ss.push(i);
    }
    dfs(length);
    cout<<dp[length]<<"\n";
    show(length);
    cout<<"\n";
//    cout<<endl<<ll<<endl;

}

int main()
{
    cin.sync_with_stdio(false);
    while(cin>>(str+1))init();

    return 0;
}
时间: 2024-11-08 23:42:59

POJ 2161 Chandelier(树状DP)的相关文章

POJ 1155 树状dp

TELE Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3856   Accepted: 2054 Description A TV-network plans to broadcast an important football match. Their network of transmitters and users can be represented as a tree. The root of the tre

POJ 1463 树状dp

Strategic game Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 6629   Accepted: 3058 Description Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the solution fast enough and then he is very sad

POJ 2342 树状dp

Anniversary party Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4606   Accepted: 2615 Description There is going to be a party to celebrate the 80-th Anniversary of the Ural State University. The University has a hierarchical structure

树状DP (poj 2342)

题目:Anniversary party 题意:给出N各节点的快乐指数,以及父子关系,求最大快乐指数和(没人职员愿意跟直接上司一起玩): 思路:从底向上的树状DP: 第一种情况:第i个员工不参与,F[i][0] += max(F[k][1], F[k][0]);(k为i的儿子) 第二种情况:第i个员工参与,F[i][1] += F[k][0]; F[i][j]表示第i个员工是否参与: 边界:F[i][0] = 0:F[i][1] = 其快乐指数: #include <iostream> #in

POJ 2309 BST 树状数组基本操作

Description Consider an infinite full binary search tree (see the figure below), the numbers in the nodes are 1, 2, 3, .... In a subtree whose root node is X, we can get the minimum number in this subtree by repeating going down the left node until t

洛谷P1122 最大子树和 (树状dp)

题目描述 小明对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题.一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿时想到了一个有关修剪花卉的问题.于是当日课后,小明就向老师提出了这个问题: 一株奇怪的花卉,上面共连有N 朵花,共有N-1条枝干将花儿连在一起,并且未修剪时每朵花都不是孤立的.每朵花都有一个“美丽指数”,该数越大说明这朵花越漂亮,也有“美丽指数”为负 数的,说明这朵花看着都让人恶心.所谓“修剪”,意为:去掉其中的一条枝条,这样一株花就成了两株,扔掉

poj1947--Rebuilding Roads(树状dp)

Rebuilding Roads Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 9496   Accepted: 4316 Description The cows have reconstructed Farmer John's farm, with its N barns (1 <= N <= 150, number 1..N) after the terrible earthquake last May. The

洛谷P2015 二叉苹果树(树状dp)

题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来描述一根树枝的位置.下面是一颗有4个树枝的树 2 5 \ / 3 4 \ / 1 现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果. 给定需要保留的树枝数量,求出最多能留住多少苹果. 输入输出格式 输入格式: 第1行2个数,N和Q(1<=Q<= N,1<N<=100). N表示树

树状DP入门

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520 题目大意:给定一棵关系树,每个节点有个权值,子节点和父节点不能同时选,问最后能选的最大价值是多少? 解题思路:树形DP入门题.由于子节点与父节点不能同时选,有人可能会用贪心思想,二者选其一肯定最优.其实不然,有可能父节点和子节点都不选,而要选子孙节点.不过只要再往深点想下,就可以得出动态规划的解法.每个节点要么选要么不选,和大多数选不选动归一样,来个dp[i][2],0表示不选,1表示不选,那

Poj 2299 Ultra-QuickSort 树状数组 解法

本题的树状数组稍微有点特点,就是需要所谓的离散化一下,开始听这个名称好像很神秘的,不过其实很简单. 就是把一个数组arr的值,其中的值是不连续的,变成一组连续的值,因为这样他们的顺序是不变的,所以,不影响结果. 例如:9 1 0 5 4 ->变为:5 2 1 4 3看出他们的相对位置不变的. 9和5为最大值在第一个位置,1和2为第二大的值在第二个位置,0和1在第一个位置等,看出对应顺序了吗? 对,就是这么简单的方法, 就叫做离散化. 如果你对counting sort熟悉的话,那么这样的思想理解