题目链接:http://codeforces.com/contest/1204/problem/D1
The only difference between easy and hard versions is the length of the string. You can hack this problem only if you solve both problems.
Kirk has a binary string ss (a string which consists of zeroes and ones) of length nn and he is asking you to find a binary string tt of the same length which satisfies the following conditions:
- For any ll and rr (1≤l≤r≤n1≤l≤r≤n) the length of the longest non-decreasing subsequence of the substring slsl+1…srslsl+1…sr is equal to the length of the longest non-decreasing subsequence of the substring tltl+1…trtltl+1…tr;
- The number of zeroes in tt is the maximum possible.
A non-decreasing subsequence of a string pp is a sequence of indices i1,i2,…,iki1,i2,…,ik such that i1<i2<…<iki1<i2<…<ik and pi1≤pi2≤…≤pikpi1≤pi2≤…≤pik. The length of the subsequence is kk.
If there are multiple substrings which satisfy the conditions, output any.
The first line contains a binary string of length not more than 20002000.
Output a binary string which satisfied the above conditions. If there are many such strings, output any of them.
110
010
010
010
0001111
0000000
0111001100111011101000
0011001100001011101000
In the first example:
- For the substrings of the length 11 the length of the longest non-decreasing subsequnce is 11;
- For l=1,r=2l=1,r=2 the longest non-decreasing subsequnce of the substring s1s2s1s2 is 1111 and the longest non-decreasing subsequnce of the substring t1t2t1t2 is 0101;
- For l=1,r=3l=1,r=3 the longest non-decreasing subsequnce of the substring s1s3s1s3 is 1111 and the longest non-decreasing subsequnce of the substring t1t3t1t3 is 0000;
- For l=2,r=3l=2,r=3 the longest non-decreasing subsequnce of the substring s2s3s2s3 is 11 and the longest non-decreasing subsequnce of the substring t2t3t2t3 is 11;
The second example is similar to the first one.
题目大意:
给出一个 串 S ,求一个串 T 要求,等长所有区间的 LIS(最长上升子序列) 相等,0 的个数尽可能多
题解:
从后向前,保证后面的解都是合法的情况下
如果当前位置的数字是 0
那么,他一定是后面以他为起点的区间的 LIS LISLIS 的一部分,这就要求 T TT 的对应位置必须为 0, 否则 LIS LISLIS 长度必然减少
如果当前位置的数字为 1
考虑,以他为起点的所有区间
对于那些 LIS LISLIS 包含它的区间,就是说 LIS LISLIS 的首项为 1 的区间,他变为0,对这些区间的 LIS LISLIS 没有影响(他们的 LIS LISLIS 长度为 1 的个数)
对于那些 LIS LISLIS 不包含他的区间,就是说 LIS LISLIS 的首项为 0 的区间,他变为0,对这些区间的 LIS LISLIS 会改变
换句话说,若想将 1 变为 0 ,必须保证后面所有的区间的 LIS LISLIS 长度必须和 1 的个数相等!!!
所以,从后向前统计 0 和 1 的数量,当 1 的个数大于等于 0 的个数时,才可以修改
代码:判断后面是否所有区间的1的个数大于0的个数竟然可以O(1)难以想象,一直以为要一遍for才行的
#include<iostream> #include<cstring> using namespace std; int main() { string s;cin>>s; int len=s.size(); int sum=0; for(int i=len-1;i>=0;i--) { if(s[i]=='0') sum++; else if(sum) sum--; else s[i]='0'; } cout<<s<<endl; return 0; }