【CF1204D】Kirk and a Binary String【结论题】【LIS】
生活随笔
收集整理的這篇文章主要介紹了
【CF1204D】Kirk and a Binary String【结论题】【LIS】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
傳送門
題意:給一個01串SSS,求一個等長的01串TTT
∣S∣≤100000|S| \leq 100000∣S∣≤100000
對于一個01串SSS,我們稱它是固定的,當且僅當不存在一個長度相同的01串TTT,它們所有對應位置的子串LIS\text{LIS}LIS相同(即修改任意一個位置都會改變LIS\text{LIS}LIS),并且規定空串是固定的。
- 兩個固定的串拼起來仍然是固定的。如果修改了一個位置,根據定義,這個位置原來歸屬的串的LIS\text{LIS}LIS一定發生了變化。
- 一個固定的串0和1個數相等,LIS\text{LIS}LIS等于其長度的一半,即全選0或全選1。前面和下一條遞歸證明,邊界為空串。后面由于一組01(見下一條)的1一定在0的前面,最多只有1的貢獻。
- 一個固定的串前面添“1”,后面添“0”后仍然固定。和上一條遞歸證明,修改中間同理,修改兩邊一定會增加1。
我們在原串中刪除所有極大的固定子串,由于沒有“10”,所以剩下的一定是“00000……11111”
由定義,固定子串是不能修改的
【解法一】
我們發現這玩意就是括號匹配
用個棧維護一下,得到剩下的字符
然后把后面的一坨1都改成0。顯然不能改更多的。
這樣對于任意一個子串,把它的極大固定子串挖出來,由于后綴的“1”可能改成了“0”,把影響的段改成“全選0”后LIS\text{LIS}LIS不會變化,可以保證合法。
【解法二】
結論:某個1可以改為0,當且僅當修改后整個串的LIS\text{LIS}LIS不變。
其實本質是相同的。如果某個位置的1在某個固定子串中,顯然修改會改變這個子串的LIS\text{LIS}LIS,并且會改變原串的LIS\text{LIS}LIS。否則對LIS\text{LIS}LIS不會產生影響。
倒著DP一下即可。
#include <iostream> #include <cstdio> #include <cstring> #include <cctype> #define MAXN 100005 using namespace std; char s[MAXN]; int pre0[MAXN],suf1[MAXN],dp[MAXN]; int main() {scanf("%s",s+1);int n=strlen(s+1);for (int i=1;i<=n;i++) pre0[i]=pre0[i-1]+(s[i]=='0');for (int i=n;i>=1;i--) suf1[i]=suf1[i+1]+(s[i]=='1');for (int i=n;i>=1;i--) dp[i]=(s[i]=='1'? max(suf1[i],dp[i+1]):dp[i+1]+1);int now=0;for (int i=1;i<=n;i++)if (s[i]=='0'||now+1+dp[i+1]<=dp[1]) putchar('0'),++now;else putchar('1');return 0; }總結
以上是生活随笔為你收集整理的【CF1204D】Kirk and a Binary String【结论题】【LIS】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何截屏快捷键 截屏的快捷键操作方法
- 下一篇: 【CF1182D】Complete Mi