3D--最小代价回文串

给你一个序列由),(,?组成,第i个?变成左括号,和右括号的代价不同,现在让你组成一个回文序列并让其花费的代价最少

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <stack>
#include <map>
#include <queue>
using namespace std;

struct cost {
    int p;
    int v;
    bool operator < (const cost& a) const {
        return v < a.v;
    }
};

cost make(int p, int v) {
    cost ret;
    ret.p = p;
    ret.v = v;
    return ret;
}

char str[50004];
int main() {
    scanf("%s", str);
    int cnt = 0;
    int len = strlen(str);
    int a, b;
    priority_queue<cost> q;

    long long ans = 0;
    for (int i = 0; i < len; i++) {
        cnt += str[i] == ‘(‘;
        cnt -= str[i] == ‘)‘ || str[i] == ‘?‘;

        if (str[i] == ‘?‘) {
            scanf("%d %d", &a, &b);
            q.push(make(i, b-a));
            ans += b;
            str[i] = ‘)‘;
        }

        if (cnt < 0 && q.empty()) {
            ans = -1;
            break;
        }

        if (cnt < 0) {
            cost top = q.top();
            q.pop();
            ans = ans - top.v;
            str[top.p] = ‘(‘;
            cnt += 2;
        }
    }

    if (cnt > 0) ans = -1;
    printf("%I64d\n", ans);
    if (ans != -1) printf("%s\n", str);

    return 0;
}
时间: 2024-08-24 16:02:49

3D--最小代价回文串的相关文章

POJ 3280 Cheapest Palindrome(区间DP求改成回文串的最小花费)

题目链接:http://poj.org/problem?id=3280 题目大意:给你一个字符串,你可以删除或者增加任意字符,对应有相应的花费,让你通过这些操作使得字符串变为回文串,求最小花费.解题思路:比较简单的区间DP,令dp[i][j]表示使[i,j]回文的最小花费.则得到状态转移方程: dp[i][j]=min(dp[i][j],min(add[str[i]-'a'],del[str[i]-'a'])+dp[i+1][j]); dp[i][j]=min(dp[i][j],min(add[

关于回文串的DP问题

问题1:插入/删除字符使得原字符串变成一个回文串且代价最小 poj 3280 Cheapest Palindrome 题意:给出一个由m中字母组成的长度为n的串,给出m种字母添加和删除花费的代价,求让给出的串变成回文串的代价. Sol: 插入和删除等价,因此只需要保留 min(插入代价,删除代价)作为调整字符串的代价 如果 s[i]==s[j],那么将区间(i,j)变为回文串的代价和将区间(i+1,j-1)变为回文串的代价相同,因为此时不需要修改 如果不同,必然要将 s[i]和s[j]改为同一字

NYOJ 1023 还是回文(DP,花最少费用形成回文串)

1 /* 2 题意:给出一串字符(全部是小写字母),添加或删除一个字符,都会产生一定的花费. 3 那么,将字符串变成回文串的最小花费是多少呢? 4 5 思路:如果一个字符串增加一个字符 x可以形成一个回文串,那么从这个字符串中删除这个字符 x 6 同样也能形成回文串! 7 所以我们只记录删除,和增加这个字符 x 的最小的费用就好了!->转变成添加多少个字符形成回文串费用最少! 8 9 str[i]!=str[k] 10 dp[i][j]=min(dp[i][j-1]+cost[str[k]-'a

回文串划分

题目: 有一个字符串S,求S最少可以被划分为多少个回文串. 例如:abbaabaa,有多种划分方式. a|bb|aabaa - 3 个回文串 a|bb|a|aba|a - 5 个回文串 a|b|b|a|a|b|a|a - 8 个回文串 其中第1种划分方式的划分数量最少. Input 输入字符串S(S的长度<= 5000). Output 输出最少的划分数量. Sample Input abbaabaa Sample Output 3 分析:题目意思还是很好懂的,不像比赛的几个题目我连题意都没看懂

YZOI Easy Round 2_回文串 string

原文链接:http://laphets1.gotoip3.com/?id=18 Description 给出一个由小写字母组成的字符串,其中一些字母被染黑了,用?表示.已知原来的串不是 一个回文串,现在让你求出字典序最小的可能的串.像’a’,’aba’,’abba’这样对称的串叫做回 文串. 每个测试点有5 组小测试点. Input 5 行,5 个字符串. Output 5 行,5 个字符串.若无解,输出”Orz,I can not find it!” 这个题目主要就是利用了一种贪心的思想  总

UVA - 11584 划分字符串的回文串子串; 简单dp

/** 链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34398 UVA - 11584 划分字符串的回文串子串: 简单dp 题目大意: 给一个字符串, 要求把它分割成若干个子串,使得每个子串都是回文串.问最少可以分割成多少个. 定义:dp[i]表示前0~i内的字符串划分成的最小回文串个数: dp[i] = min(dp[j]+1 | j+1~i是回文串); 先预处理flag[i][j]表示以i~j内的字符串为回文串

uva--10716Evil Straw Warts Live +回文串+贪心

题意: 输入一个字符串,我们可以交换这个字符串中的相邻字符:问至少经过多少步交换可以得到一个回文串:如果无论怎么交换都得不到回文串,输出"Impossible": 思路: 首先由回文串的定义和性质,可以得到两种不可能情况:1.当这个串长度为奇数时,如果出现次数为奇数次字母的数目不为1,则显然不可能.2.当这个串长度为偶数时,如果出现次数为奇数次字母的个数大于0,则不可能. 除去这两种不可能的情况后,这个串就一定可以转成回文串.我们只需要考虑0--len/2(len为串长)的部分,对于第

UVa 11584 划分成回文串

https://vjudge.net/problem/UVA-11584 题意: 给出一串字符,把它划分成尽量少的回文串. 思路: 用d[i]表示划分到i时所能划分的最小个数,转移方程为d[i]=min{d[i],d[j]+1},当然前提是j+1~i是回文串,我们可以预处理计算出所有的回文串,这样转移时就比较方便. 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<s

[LeetCode] Palindrome Partitioning II 拆分回文串之二

Given a string s, partition s such that every substring of the partition is a palindrome. Return the minimum cuts needed for a palindrome partitioning of s. For example, given s = "aab", Return 1 since the palindrome partitioning ["aa"