[bzoj2213][Poi2011]Difference_动态规划
2018-08-26 13:58
197 查看
Difference bzoj-2213 Poi-2011
题目大意:已知一个长度为n的由小写字母组成的字符串,求其中连续的一段,满足该段中出现最多的字母出现的个数减去该段中出现最少的字母出现的个数最大。求这个个数。
注释:$1\le n\le 10^6$。
想法:“在线”的dp题。
状态:$dp[i][j]$表示在当前位置,字母$i$与字母$j$之间的最大差,$dp2[i][j]$表示出现次数的差。
这样的话就可以拿来更新答案了。
至于复杂度的的话,因为每次从$i$更新到$i+1$只会更改52个值,所以复杂度是$O(n)$的。
最后,附上丑陋的代码... ...
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define K 50 using namespace std; int sum[K],f[K][K],g[K][K],c[K][K],h[K][K],d[K][K],ans; char str[1000010]; void update(int a , int b) { if(c[a][b] < sum[b]) ans = max(ans , f[a][b] - g[a][b]); else if(d[a][b] < sum[b]) ans = max(ans , f[a][b] - h[a][b]); if(f[a][b] < g[a][b]) { if(c[a][b] < sum[b]) h[a][b] = g[a][b] , d[a][b] = c[a][b]; g[a][b] = f[a][b] , c[a][b] = sum[b]; } else if(c[a][b] < sum[b] && f[a][b] < h[a][b]) h[a][b] = f[a][b] , d[a][b] = sum[b]; } int main() { int n,t; scanf("%d%s" , &n , str + 1); for(int i=1;i<=n;i++) { t=str[i]-'a'; sum[t]++; for(int j=0;j<K;j++) if(t != j) f[t][j]++,update(t,j),f[j][t]--,update(j,t); } printf("%d\n",ans); return 0; }
小结:挺好的题(好像是lzh的考试题)。
相关文章推荐
- BZOJ2213: [Poi2011]Difference
- bzoj 2213: [Poi2011]Difference
- BZOJ2213 [Poi2011]Difference 【乱搞】
- bzoj 2213: [Poi2011]Difference 乱搞
- bzoj2213: [Poi2011]Difference(思维题)
- BZOJ2213: [Poi2011]Difference
- BZOJ 2213: [Poi2011]Difference
- BZOJ 2216 Poi2011 Lightning Conductor 动态规划
- 2213: [Poi2011]Difference
- 【bzoj2213】[Poi2011]Difference dp
- 【BZOJ2213】[Poi2011]Difference DP
- 【bzoj2213】[Poi2011]Difference dp
- 【BZOJ 2216】【POI 2011】[动态规划][决策点单调优化]Lightning Conductor
- BZOJ2527 [Poi2011]Meteors 【整体二分 + 树状数组】
- bzoj2216[POI2011] Lightning Conductor
- BZOJ 2527: [Poi2011]Meteors
- BZOJ2276: [Poi2011]Temperature
- [BZOJ2212][POI2011]Tree Rotations(线段树合并)
- 【jzoj4931】【bzoj4380】【POI2015】【Myjnie】【动态规划】
- BZOJ 2280 Poi2011 Plot 二分答案+随机增量法