bzoj2958 & bzoj3269
来源:互联网 发布:做程序员需要什么条件 编辑:程序博客网 时间:2024/06/16 17:37
Description
给出一个长度为N由B、W、X三种字符组成的字符串S,你需要把每一个X染成B或W中的一个。
对于给出的K,问有多少种染色方式使得存在整数a,b,c,d使得:
1<=a<=b<c<=d<=N
Sa,Sa+1,...,Sb均为B
Sc,Sc+1,...,Sd均为W
其中b=a+K-1,d=c+K-1
由于方法可能很多,因此只需要输出最后的答案对109+7取模的结果。
Input
第一行两个正整数N,K
第二行一个长度为N的字符串S
Output
一行一个整数表示答案%(109+7)。
Sample Input
5 2
XXXXX
Sample Output
4
数据约定
对于20%的数据,N<=20
对于50%的数据,N<=2000
对于100%的数据,1<=N<=10^6,1<=K<=10^6
HINT
Source
中国国家队清华集训 2012-2013 第一天
题解:
我的算法和网上别人的好像不太一样。。。
每次转移都是一段B或一段W,所以记dp[i][j][k]为算完i位,j=0,1,2表示没有完成B,没有完成W,BW都完成了,k表示上一个是B还是W。
普通的dp直接枚举从哪一位转移,长度大于k强制修改j。
时间复杂度O(n^2)。
看到转移是把一段dp求和,记录dp的前缀和即可。
时间复杂度O(n)。
#include <stdio.h>#include <algorithm> using namespace std; //long longconst int mod = 1000000007;const int maxn = 1200000;int n , k;char z[maxn];int dp[maxn][3][3] , last[maxn][3] , sum[maxn][3][3];void work () { int i , j , l; scanf ( "%d%d" , &n , &k ); scanf ( "%s" , z + 1 ); if ( k > n ) { printf ( "0\n" ); return ; } j = n; for ( i = n ; i >= 1 ; i-- ) { if ( j > i ) j = i; while ( j >= 0 && z[j] != 'W' ) j--; last[i][1] = j; } j = n; for ( i = n ; i >= 1 ; i-- ) { if ( j > i ) j = i; while ( j >= 0 && z[j] != 'B' ) j--; last[i][2] = j; } //for ( i = 1 ; i <= n ; i++ ) printf ( "%d %d\n" , last[i][1] , last[i][2] ); //if ( z[1] != 'W' ) { // if ( k != 1 ) dp[1][0][1] = 1; // else dp[1][1][1] = 1; //} dp[0][0][1] = dp[0][0][2] = sum[0][0][1] = sum[0][0][2] = 1; //if ( z[1] != 'B' ) dp[1][0][2] = 1; //sum[1][0][1] = dp[1][0][1]; sum[1][1][1] = dp[1][1][1]; //sum[1][0][2] = dp[1][0][2]; for ( i = 1 ; i <= n ; i++ ) { if ( last[i][2] <= i ) { dp[i][0][2] += (sum[i-1][0][1] - (last[i][2]!=0?sum[last[i][2]-1][0][1]:0) + mod) % mod; dp[i][0][2] %= mod; } l = i - 1 - k + 1; if ( last[i][1] <= i ) { if ( last[i][1] <= l ) { dp[i][0][1] += (sum[i-1][0][2] - sum[l][0][2] + mod) % mod; dp[i][0][1] %= mod; dp[i][1][1] += (sum[l][0][2] - (last[i][1]!=0?sum[last[i][1]-1][0][2]:0) + mod) % mod; dp[i][1][1] %= mod; } else { dp[i][0][1] += (sum[i-1][0][2] - (last[i][1]!=0?sum[last[i][1]-1][0][2]:0) + mod) % mod; dp[i][0][1] %= mod; } } //printf ( "%d\n" , l ); /* printf ( "%d %d %d %d\n" , dp[1][0][1] , dp[1][0][2] , (sum[i-1][0][1] - sum[last[i][2]-1][0][1]), (sum[i-1][0][2] - sum[last[i][1]-1][0][2]) );*/ if ( last[i][2] <= i ) { if ( last[i][2] <= l ) { dp[i][1][2] += (sum[i-1][1][1] - sum[l][1][1] + mod) % mod; dp[i][1][2] %= mod; dp[i][2][2] += (sum[l][1][1] - (last[i][2]!=0?sum[last[i][2]-1][1][1]:0) + mod) % mod; dp[i][2][2] %= mod; } else { dp[i][1][2] += (sum[i-1][1][1] - (last[i][2]!=0?sum[last[i][2]-1][1][1]:0) + mod) % mod; dp[i][1][2] %= mod; } } if ( last[i][1] <= i ) { dp[i][1][1] += (sum[i-1][1][2] - (last[i][1]!=0?sum[last[i][1]-1][1][2]:0) + mod) % mod; dp[i][1][1] %= mod; } if ( last[i][2] <= i ) { dp[i][2][2] += (sum[i-1][2][1] - (last[i][2]!=0?sum[last[i][2]-1][2][1]:0) + mod) % mod; dp[i][2][2] %= mod; } if ( last[i][1] <= i ) { dp[i][2][1] += (sum[i-1][2][2] - (last[i][1]!=0?sum[last[i][1]-1][2][2]:0) + mod) % mod; dp[i][2][1] %= mod; } for ( j = 1 ; j <= 6 ; j++ ) sum[i][(j-1)/2][(j-1)%2+1] = (sum[i-1][(j-1)/2][(j-1)%2+1]+dp[i][(j-1)/2][(j-1)%2+1]) % mod; } //for ( i = 0 ; i <= n ; i++ ) printf ( "%d %d %d %d %d %d\n" , dp[i][0][1] , dp[i][0][2] , dp[i][1][1] , dp[i][1][2] , dp[i][2][1] , dp[i][2][2] ); //printf("\n"); //for ( i = 0 ; i <= n ; i++ ) printf ( "%d %d %d %d %d %d\n" , sum[i][0][1] , sum[i][0][2] , sum[i][1][1] , sum[i][1][2] , sum[i][2][1] ,sum[i][2][2] ); printf ( "%d\n" , ((dp[n][2][1] + dp[n][2][2]) % mod + mod ) % mod);}int main () { //FILE *fpr = freopen ( "bzoj3269.in" , "r" , stdin ); //FILE *fpw = freopen ( "bzoj3269.out" , "w" , stdout ); work (); return 0;}
0 0
- bzoj2958 & bzoj3269
- bzoj2958: 序列染色
- BZOJ2958: 序列染色
- bzoj2958序列染色
- bzoj2958(DP,补偿转移)
- 单击菜单自动调用扫一扫功能,遇到的问题和大家分享一下
- Xcode编程常用快捷键
- eclipse tomcat MySQL环境配置
- 这是我的第一张博客
- 文章标题
- bzoj2958 & bzoj3269
- java知识总结(四)this与static详解
- 微博轻量级RPC框架Motan
- [Leetcode]Two Sum II - Input array is sorted
- disconf 报错 Will not attempt to authenticate using SASL (unknown error)
- Spring在代码中获取bean的几种方式
- node.js学习日记——(6)
- windows下查看dns缓存和刷新缓存
- Node js 安装与配置