hdu6078
来源:互联网 发布:win7禁止软件安装 编辑:程序博客网 时间:2024/06/06 16:54
多校第四场1012
Wavel Sequence
题意是定义一种波浪数列,满足a1< a2 > a3 < a4 > a5
给两个数列a,b,选出a b的一个公共子串,且是一个波浪数列,问这样的方案有多少种。
这个题相当于公共子序列里再套一个dp
定义dp[i][j][k]为a串前i个且以b串j结尾且上升状态为k时的方案数,那么就可以枚举转移了。
dp[i][j][0] += dp[i-1][j][0] ; dp[i][j][1] += dp[i-1][j][1] ; if(a[i]== b[j] { dp[i][j][0] += dp[i-1][k][1](0<=k<j && b[k] < b[j]) dp[i][j][1] += dp[i-1][k][0] (0<=k < j &&b[k] > b[j] ) }
这样子基本上就算是转移完了这个方程。
但是!!!!!!!!最最最重要的是,这里存在了一个k需要枚举,也就是说这个dp是三维的,串长的2000,三维显然不现实。现场做的时候完全束手无策。
很绝望,因为感觉真的很菜,赛后看题解也看不懂,最后看别人博客的时候恍然大悟。其实非常好解决,注意到需要枚举的情况是当a[i] == b[j]的时候,那么在这种情况下,在外层循环枚举i的时候,把所有b[j]< a[i]和b[j] > a[i]的方案都和起来,然后转移的时候就不用一个个的去枚举了。很轻松地就把方程从三维降到了二维。
这种细节真的很重要,以后在dp的时候要注重这些可以优化的细节。
#include<cmath>#include<algorithm>#include<cstring>#include<string>#include<set>#include<map>#include<time.h>#include<cstdio>#include<vector>#include<list>#include<stack>#include<queue>#include<iostream>#include<stdlib.h>using namespace std;#define LONG long longconst LONG INF=0x3f3f3f3f;const LONG MOD=998244353;const double PI=acos(-1.0);#define clrI(x) memset(x,-1,sizeof(x))#define clr0(x) memset(x,0,sizeof x)#define clr1(x) memset(x,INF,sizeof x)#define clr2(x) memset(x,-INF,sizeof x)#define EPS 1e-10#define lson l , mid , rt<< 1#define rson mid + 1 ,r , (rt<<1)+1#define root 1, n , 1LONG dp[2105][2105][2] ;LONG a[2105];LONG b[2105] ;LONG Sum[2105][2] ;int main(){ int T; cin >> T; while( T -- ) { int n, m ; clr0(dp ) ; cin >> n>> m ; for(int i = 1 ;i<= n ; ++ i) cin >> a[i] ; for(int j = 1; j<= m ;++ j) cin >>b[j] ; for(int i = 0 ;i <= n + 10 ; ++ i) dp[i][0][0] = 1; for(int i = 1;i <= n ; ++ i) { clr0(Sum) ; LONG Sum0 =1 ; LONG Sum1 = 0; for(int j = 1;j <= m ; ++j) { if(a[i] == b[j]) { dp[i][j][0] += dp[i-1][j][0] ; dp[i][j][1] += dp[i-1][j][1]; ( dp[i][j][0] += Sum1 ) %= MOD ; ( dp[i][j][1] += Sum0 ) %= MOD ; } else { ( dp[i][j][0] += dp[i-1][j][0] ) %= MOD ; ( dp[i][j][1] += dp[i-1][j][1] ) %= MOD ; } if( b[j] < a[i] ) ( Sum1 += dp[i][j][1] ) %= MOD ; if( b[j] > a[i]) ( Sum0 += dp[i][j][0] ) %= MOD ; } } LONG ans = 0 ; for(int i = 1;i <= m ; ++i) ans += dp[n][i][0] +dp[n][i][1] ,ans %= MOD ; cout<<ans<<endl; }}
阅读全文
1 0
- hdu6078
- HDU6078-Wavel Sequence
- hdu6078 wave sequence dp
- 2017第四次多校联合hdu6078
- HDU6078 Wavel Sequence(动态规划)
- hdu6078 Wavel Sequence 2017多校第四场1012 dp
- 2017多校训练Contest4: 1012 Wavel Sequence hdu6078
- hdu6078 Wavel Sequence(分析优化递推过程,好题)
- 学生信息管理系统之数据库
- HDOj 2546 饭卡 (动态规划)
- apache-comnons系列之commons-configuration2 学习笔记
- NSSortDescriptor 的使用-------快速排序
- 使用mybatis-generator添加自定义分页插件时提示无法实例化插件类
- hdu6078
- 工具篇 | 常用邮箱POP3/SMTP设置
- 按钮默认和窗体设定----学生管理系统之用户体验
- 奇妙的音乐
- 字符串练习——识别合法帧
- Python 基础
- 1003. Emergency (25)(*****)
- 2017百度之星资格赛:1003. 度度熊与邪恶大魔王
- 递归计算逆波兰表达式