先进行离散化,然后再预处理出所有位置的下一个元素,做好这一步对时间的优化非常重要。

剩下的就是一般的DP了。区间DP

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; const int maxn = ;
const ll mod = 1e9 + ; ll dp[maxn][maxn], f[maxn][maxn], a[maxn];
int nex[maxn][maxn], pre[maxn][maxn];
pair<ll, int>discre[maxn]; int main(){
int n;while(~scanf("%d", &n)){
for(int i = ; i <= n; i ++){
scanf("%lld", &a[i]);
discre[i].first = a[i];
discre[i].second = i;
} sort(discre + , discre + + n);
discre[].first = -;
int cnt = ;
for(int i = ; i <= n; i ++){
if(discre[i].first != discre[i - ].first) cnt ++;
a[discre[i].second] = cnt;
}
a[] = a[n + ] = cnt + ;
memset(dp, -, sizeof(dp));
memset(nex, , sizeof(nex));
memset(pre, , sizeof(pre));
for(int i = ; i <= n + ; i ++){
for(int j = i + ; j <= n + ; j ++)
if(!nex[i][a[j]]) nex[i][a[j]] = j;
for(int j = i - ; j >= ; j --)
if(!pre[i][a[j]]) pre[i][a[j]] = j;
}
for(int l = n + ; l >= ; l -- ){
ll ans1 = , ans2 = ;
for(int r = l; r <= n + ; r ++){
ll tmp1, tmp2;
if(l == r){
dp[l][r] = f[l][r] = ;
continue;
} if(a[r - ] <= a[l]){
tmp1 = dp[nex[l][a[r-]]][pre[r-][a[r-]]];
tmp2 = f[nex[l][a[r-]]][pre[r-][a[r-]]];
if(ans1 == tmp1) ans2 = (ans2 - tmp2 + mod) % mod;
if(ans1 < tmp1) ans1 = tmp1, ans2 = tmp2;
tmp1 = dp[nex[l][a[r-]]][r - ];
tmp2 = f[nex[l][a[r-]]][r - ];
if(ans1 == tmp1) ans2 = (ans2 + tmp2) % mod;
if(ans1 < tmp1) ans1 = tmp1, ans2 = tmp2;
} if(a[l] == a[r]){
dp[l][r] = ans1 + ;
f[l][r] = ans2;
}else dp[l][r] = f[l][r] = ;
}
}
ll ans1 = , ans2 = ;
for(int i = ; i <= cnt; i ++){
if(dp[nex[][i]][pre[n+][i]] > ans1){
ans1 = dp[nex[][i]][pre[n+][i]];
ans2 = f[nex[][i]][pre[n+][i]];
}else if(ans1 == dp[nex[][i]][pre[n+][i]])
ans2 = (ans2 + f[nex[][i]][pre[n+][i]]) % mod;
}
printf("%lld %lld\n",ans1, ans2);
}
return ;
}

Palindrome Bo (预处理 + 区间DP)的更多相关文章

  1. LightOJ1044 Palindrome Partitioning(区间DP+线性DP)

    问题问的是最少可以把一个字符串分成几段,使每段都是回文串. 一开始想直接区间DP,dp[i][j]表示子串[i,j]的答案,不过字符串长度1000,100W个状态,一个状态从多个状态转移来的,转移的时 ...

  2. HDU Palindrome subsequence(区间DP)

    Palindrome subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65535 K (Java/Oth ...

  3. 1044 - Palindrome Partitioning(区间DP)

    题目大意: 给你一个字符串,问这个字符串最少有多少个回文串. 区间DP直接搞     #include<cstdio> #include<cstring> #include&l ...

  4. Palindrome subsequence(区间dp+容斥)

    In mathematics, a subsequence is a sequence that can be derived from another sequence by deleting so ...

  5. HDU 4632 Palindrome subsequence (区间DP)

    Palindrome subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65535 K (Java/ ...

  6. HDU 4632 Palindrome subsequence(区间dp)

    Palindrome subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65535 K (Java/ ...

  7. Light oj 1044 - Palindrome Partitioning(区间dp)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1044 dp[i][j]表示i到j直接的最小回文区间个数,直接看代码 #include ...

  8. 【HDU4632 Palindrome subsequence】区间dp

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4632 题意:给你一个序列,问你该序列中有多少个回文串子序列,可以不连续. 思路:dp[i][j]表示序 ...

  9. hdu4632 Palindrome subsequence 回文子序列个数 区间dp

    Palindrome subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65535 K (Java/ ...

随机推荐

  1. AVD启动报错:Running an x86 based Android Virtual Device (AVD) is 10x faster

    1.cmd窗口中输入emulator -avd test 启动AVD时报错: Running an x86 based Android Virtual Device (AVD) is 10x fast ...

  2. adb devices offline的解决办法

    手机通过USB线连接电脑后,输入adb devices 识别为 offline,如图: 解决办法如下: (0) 换数据线.换主机后面的USB口先试一下 (1) 重启adb服务 adb kill-ser ...

  3. elasticsearch安装IK分词插件

    一 打开网页:https://github.com/medcl/elasticsearch-analysis-ik/releases 这个是ik相关的包,找到你想下载的版本,下载对应的zip包 二 然 ...

  4. linux popen()函数使用

    默认管道只能处理标准输出,不能处理标准错误输出 所以在popen()函数中运行的命令若有标准错误输出,调用者无法捕获 解决办法: 1.将标准错误输出重定向到标准输出2>&1,这样调用者能 ...

  5. java 数组(一)

    java的数组操作和C#是一样的,不多说明. public class ArrayDemo{ public static void main(String[] args){ //数组的定义 数据类型[ ...

  6. scp & cat远程文件操作

    对拷文件夹 (包括文件夹本身) scp -r /home/wwwroot/www/charts/util root@192.168.1.65:/home/wwwroot/limesurvey_back ...

  7. cudnn升级之后caffe无法训练的问题

    由于安装新版本的TensorFlow需要cudnn6.0因此用6.0将原来的 5.0替换了,后来又用之前编译好的caffe进行训练,发现caffe会去找5.0的cudnn,然后就报错了,不能正常训练. ...

  8. python练习题-day1

    1.使用while循环输入 1 2 3 4 5 6     8 9 10 count=0 while count<10: count+=1 if count==7: continue print ...

  9. sed 操作命令

    sed介绍 grep 只能过滤文件内容,sed既能过滤文件内容同时还能对文件内容进行修改.  sed 算是一种编程语言,它有自己的固定语法. sed是一种行编辑器,sed会在内存中开辟一块独立的空间( ...

  10. 【SVD、特征值分解、PCA关系】

    一.SVD    1.含义: 把矩阵分解为缩放矩阵+旋转矩阵+特征向量矩阵. A矩阵的作用是将一个向量从V这组正交基向量的空间旋转到U这组正交基向量的空间,并对每个方向进行了一定的缩放,缩放因子就是各 ...