当前位置:网站首页>【HDU6357】Hills And Valleys(DP)
【HDU6357】Hills And Valleys(DP)
2022-06-11 07:23:00 【CaptainHarryChen】
题意
给定一个数组A[],元素均在[0,9],可以翻转一段区间,求最长不下降子序列,并输出翻转区间
题解
很巧妙的DP
因为值域很小,我们可以枚举需要翻转的区间值出一个数组B[],规划好我们要求得的序列的大致趋向。
如我们翻转的区间的值为[7,3],则构建B数组为B[]={0,1,2,3,7,6,5,4,3,7,8,9},dp时按照B数组中的元素,进行转移。
定义dp状态:dp[i][j]为匹配到A串的第i位,B串的第j位,最长不下降子序列的长度:
转移为dp[i][j] = min ( dp[i][j-1], dp[i-1][j]+(A[i]==B[j]) )
从dp[i][j-1]转移是为了保证j越大,dp[i][j]也越大,使得当i固定,dp[i][j]保持不下降
从dp[i-1][j]转移即在A串中添加一位A[i],如果A[i]值在匹配的B串位置之后,则最长不下降序列可增加一位,因为我们已经保证dp[i][j]>=dp[i][j-1],所以只用判断A[i]==B[j]即可。
因为需要输出翻转方案,我们用path[i][j]数组记录dp转移路径,dp完成后,利用path恢复我们从B中选出来的元素(作为最长不下降子序列的元素),存在数组C[i]里,然后判断从哪一位开始翻转即可。
注意:如果没有翻转,需把翻转区间长度设为1(自己跟自己翻转)
代码
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=100005,MAXL=33;
int N,M;
int A[MAXN],B[MAXL];
int dp[MAXN][MAXL];
pair<int,int> path[MAXN][MAXL],C[MAXN];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&N);
for(int i=1;i<=N;i++)
scanf("%1d",&A[i]);
int ans=0,ansl,ansr;
for(int x=0;x<10;x++)
for(int y=x;y<10;y++)
{
M=0;
int l,r;
for(int i=0;i<=x;i++)
B[++M]=i;
l=M+1;
for(int i=y;i>=x;i--)
B[++M]=i;
r=M;
for(int i=y;i<10;i++)
B[++M]=i;
for(int i=1;i<=N;i++)
for(int j=1;j<=M;j++)
{
if(dp[i][j-1]<dp[i-1][j]+(A[i]==B[j]))
{
dp[i][j]=dp[i-1][j]+(A[i]==B[j]);
path[i][j]=make_pair(i-1,j);
}
else
{
dp[i][j]=dp[i][j-1];
path[i][j]=make_pair(i,j-1);
}
}
if(dp[N][M]>ans)
{
ans=dp[N][M];
int p=N,q=M,top=ans;
ansl=-1,ansr=-1;
pair<int,int> t;
while(p&&q)
{
t=path[p][q];
if(dp[t.first][t.second]+1==dp[p][q]&&A[p]==B[q])
C[top--]=make_pair(p,q);
p=t.first;
q=t.second;
}
int k;
for(k=1;k<=ans&&C[k].second<l;k++);
ansl=C[k].first;
for(;k<=ans&&C[k].second<=r;k++);
ansr=C[k-1].first;
if(ansl>ansr)
ansl=ansr=1;
}
}
//printf("%d\n",ans);
printf("%d %d %d\n",ans,ansl,ansr);
}
return 0;
}边栏推荐
- Adventure of small X
- 软件测试周刊(第75期):唯有平视,才能看见真实的自己。
- Directrix of ellipse
- Outer margin collapse
- 二、用户登录和注册
- Use definite integral to calculate triangle area
- 【Oracle 数据库】奶妈式教程day02 数据库管理工具SQLPLUS的使用
- The rotation of the earth and the moon (II)
- MS office level II wrong question record [9]
- Classification of MNIST datasets with keras
猜你喜欢
![[advanced concurrency] - thread pool summary](/img/69/dc8146dafc30f8a8efa012b67aa05c.png)
[advanced concurrency] - thread pool summary

Use definite integral to calculate triangle area

Mistakes in Niuke JS exercise

資深OpenStacker - 彭博、Vexxhost昇級為OpenInfra基金會黃金成員

JVM Learning record (7) - - class Loading Process and parent delegation Model

一、SQLServer2008安装(带密码)、创建数据库、C#窗体项目测试

2022低压电工操作证考试题模拟考试平台操作

Education expert wangzhongze solves students' problems with one move

C memory alignment
![[STL source code analysis] summary notes (5): a good helper for understanding iterators --list](/img/a7/c54bfb6a03c04e4ffeafdfcf8cedc2.jpg)
[STL source code analysis] summary notes (5): a good helper for understanding iterators --list
随机推荐
1190. invert the substring between each pair of parentheses
Error occurred in pycharm DeprecatedEnv: Env FrozenLake-v0 not found (valid versions include [‘FrozenLake-v1‘])
Smart pointer (simple version)
Senior openstacker - Bloomberg, vexxhost upgraded to the Gold member of openinfra Foundation
CMAP of Matplotlib
The gap between the parent box and the child box
正则表达式匹配
Sdl-2 thread logic
【CF#654 (Div. 2)】A. Magical Sticks
The maximum number of divisors of numbers in the int range is 1536
Mistakes in Niuke JS exercise
Server parameter adjustment record
Decimal to binary
@Jsonproperty annotation
SQLZOO刷题记录-3
2022低压电工操作证考试题模拟考试平台操作
MS office level II wrong question record [7]
C+tinycthread implementation thread
一、SQLServer2008安裝(帶密碼)、創建數據庫、C#窗體項目測試
Directrix of ellipse