码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 1296E2. String Coloring (hard version)

时间:2020-02-05 18:49:49      阅读:87      评论:0      收藏:0      [点我收藏+]

标签:ref   res   转换   onclick   har   tar   href   hdu1257   序列   

这道题和HDU1257一模一样,一开始窝都用贪心直接解,没法理解为什么求一个最长下降序列,直到看了巨巨的题解,先给出一个定理,Dilworth‘s theorem,离散学不好,补题两行泪,该定理是说,对于任意的偏序集,其最长反链的长度与能分解的最少的链数(chain decomposition)相等,反链(anti-chain)是指该链内任意元素不可比(incomparable),链(chain)则是都可比,回到这一题,要求的是递增链的最小数目,即递增链最小分解数,转换成求其递减链的最长长度即可,转换成了dp问题,先上贪心代码

技术图片
const int maxm = 2e5+5;
 
int colors[maxm], cache[maxm];
 
void run_case() {
    int n;
    string str;
    cin >> n >> str;
    int res = 1;
    for(int i = 0; i < n; ++i) {
        int c = str[i] - a;
        bool neednew = false;
        for(int j = 1; j <= res; ++j) {
            if(colors[j] <= c) {
                colors[j] = c, cache[i] = j; break;
            }
            if(j == res) neednew = true;
        }
        if(neednew) {
            colors[++res] = c, cache[i] = res;
        }
    }
    cout << res << "\n";
    for(int i = 0; i < n; ++i) {
        cout << cache[i] << " ";
    }
}
 
int main() {
    ios::sync_with_stdio(false), cin.tie(0);
    run_case();
    //cout.flush();
    return 0;
}
贪心

设dp[i]表示以i结尾的最长的decrease链,则状态转移为:

1.若str[i] < str[i-1], dp[i]=dp[i-1]+1

2.若str[i] >= str[i-1] dp[i]=1

但是,这个状态与m段最大子段和一样,i的上一个increase字符不一定是i-1,例如bca,dp[a]为2而不为1,我们就模仿m段最大子段和,设maxdp[i]为字母i结尾的最长的decrease链长度,

则dp[i] = max(1,maxdp[pre]+1), pre表示比i大的字母,然后再用dp更新maxdp即可,maxdp[str[i]] = max(maxdp[str[i]], dp[i]),那么,我们如何恢复答案呢,看dp数组更新时,若dp[i]大于了maxdp[pre],因为我们要求的是increase链,则str[i]无法接在pre(比str[i]大的字母)后面,就要用一个新的颜色,即更新了dp[i],所以dp[i]就是答案

技术图片
void run_case() {
    int n;
    string str;
    cin >> n >> str;
    vector<int> maxdp(26);
    vector<int> dp(n, 1);
    for(int i = 0; i < n; ++i) {
        for(int c = 25; c > str[i]-a; --c) {
            dp[i] = max(dp[i], maxdp[c]+1);
        }
        maxdp[str[i]-a] = max(maxdp[str[i]-a], dp[i]);
    }
    cout << *max_element(maxdp.begin(), maxdp.end()) << "\n";
    for(int i = 0; i < n; ++i)
        cout << dp[i] << " ";
}
 
int main() {
    ios::sync_with_stdio(false), cin.tie(0);
    run_case();
    //cout.flush();
    return 0;
}
DP

 

Codeforces 1296E2. String Coloring (hard version)

标签:ref   res   转换   onclick   har   tar   href   hdu1257   序列   

原文地址:https://www.cnblogs.com/GRedComeT/p/12264496.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!