Codeforces Round #334 C. Alternative Thinking (dp)
2015-12-03 02:59
399 查看
题意:
给定一个长度为105的01序列,现要求翻转一个非空子串,就是串内0变1,1变0,求最长交替01子序列的长度,比如01010或者10101,就是5
分析:
这题可以找规律贪心,我直接xjb dp的
考虑状态dp[i][0/1][0/1]:=以第i位结尾,且这位是0/1,序列有没有翻转过的最长交替01子序列
转移就毕竟麻烦,要考虑前面的相反的最大值,用一个前缀max,同时还要维护状态取到的位置来判断是不是可以继续翻转,总之很麻烦
还好1A了−−写完了之后只是觉得dp还是弱,虽然很清楚怎么做了,但真的应该想的无比清楚再写,dp真不差这2分钟手速,一旦稍微晕了,debug的代价更高
这题还可以证明,不翻转不比翻转更优,假设不翻转是个最优状态,那么完全翻转整个串的结果是相同的,假设不成立,所以原命题成立
证明这个主要是我交的时候不小心max了没有翻转的状态,嘛所以不要慌着resubmit,仔细想想是不是真的错了
代码:
给定一个长度为105的01序列,现要求翻转一个非空子串,就是串内0变1,1变0,求最长交替01子序列的长度,比如01010或者10101,就是5
分析:
这题可以找规律贪心,我直接xjb dp的
考虑状态dp[i][0/1][0/1]:=以第i位结尾,且这位是0/1,序列有没有翻转过的最长交替01子序列
转移就毕竟麻烦,要考虑前面的相反的最大值,用一个前缀max,同时还要维护状态取到的位置来判断是不是可以继续翻转,总之很麻烦
还好1A了−−写完了之后只是觉得dp还是弱,虽然很清楚怎么做了,但真的应该想的无比清楚再写,dp真不差这2分钟手速,一旦稍微晕了,debug的代价更高
这题还可以证明,不翻转不比翻转更优,假设不翻转是个最优状态,那么完全翻转整个串的结果是相同的,假设不成立,所以原命题成立
证明这个主要是我交的时候不小心max了没有翻转的状态,嘛所以不要慌着resubmit,仔细想想是不是真的错了
代码:
// // Created by TaoSama on 2015-12-01 // Copyright (c) 2015 TaoSama. All rights reserved. // //#pragma comment(linker, "/STACK:1024000000,1024000000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; #define pr(x) cout << #x << " = " << x << " " #define prln(x) cout << #x << " = " << x << endl const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7; int n, dp [2][2], b [2][2], wh [2][2]; char s ; void getMax(int &x, int y) { x = max(x, y); } int main() { #ifdef LOCAL freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin); // freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); while(scanf("%d", &n) == 1) { scanf("%s", s + 1); memset(dp, 0, sizeof dp); memset(b, 0, sizeof b); memset(wh, 0, sizeof wh); for(int i = 1; i <= n; ++i) { int p = s[i] - '0'; //得到之前的状态 b[i][p ^ 1][0] = b[i - 1][p ^ 1][0]; b[i][p][0] = b[i - 1][p][0]; b[i][p][1] = b[i - 1][p][1]; b[i][p ^ 1][1] = b[i - 1][p ^ 1][1]; wh[i][p ^ 1][0] = wh[i - 1][p ^ 1][0]; wh[i][p][0] = wh[i - 1][p][0]; wh[i][p][1] = wh[i - 1][p][1]; wh[i][p ^ 1][1] = wh[i - 1][p ^ 1][1]; getMax(dp[i][p][0], b[i][p ^ 1][0] + 1); getMax(dp[i][p][1], b[i][p ^ 1][1] + 1); if(wh[i][p][1] == i - 1) getMax(dp[i][p ^ 1][1], b[i][p][1] + 1); getMax(dp[i][p ^ 1][1], b[i][p][0] + 1); //更新前缀max if(dp[i][p][0] > b[i][p][0]) { b[i][p][0] = dp[i][p][0]; } if(dp[i][p][1] > b[i][p][1]) { b[i][p][1] = dp[i][p][1]; } if(dp[i][p ^ 1][1] > b[i][p ^ 1][1]) { b[i][p ^ 1][1] = dp[i][p ^ 1][1]; wh[i][p ^ 1][1] = i; } // printf("dp[%d][%d][%d] = %d\n", i, 0, 0, dp[i][0][0]); // printf("dp[%d][%d][%d] = %d\n", i, 0, 1, dp[i][0][1]); // printf("dp[%d][%d][%d] = %d\n", i, 1, 0, dp[i][1][0]); // printf("dp[%d][%d][%d] = %d\n", i, 1, 1, dp[i][1][1]); } int ans = 0; for(int i = 1; i <= n; ++i) { getMax(ans, max(dp[i][0][0], dp[i][0][1])); getMax(ans, max(dp[i][1][0], dp[i][1][1])); } printf("%d\n", ans); } return 0; }
相关文章推荐
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- LFC1.0.0 版本发布
- Android px、dp、sp之间相互转换
- HP data protector软件学习1--基本角色与基本工作流程
- HP data protector软件学习2--软件组成与界面介绍
- android中像素单位dp、px、pt、sp的比较
- Android对px和dip进行尺寸转换的方法
- Android根据分辨率进行单位转换-(dp,sp转像素px)
- android 尺寸 dp,sp,px,dip,pt详解
- DP问题各种模型的状态转移方程
- POJ-1695-Magazine Delivery-dp
- nyoj-1216-整理图书-dp
- TYVJ1193 括号序列解题报告
- 对DP的一点感想
- TYVJ上一些DP的解题报告
- soj1005. Roll Playing Games
- 01背包问题
- LeetCode之Maximum Product Subarray
- DP Flow