1 条题解
-
0
自动搬运
来自洛谷,原作者为

zyj_Orz
为了伯伦希尔的荣耀,为了休伯利安的名义!!!搬运于
2025-08-24 21:53:21,当前版本为作者最后更新于2019-01-28 08:44:57,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
排版已订正。
DP题。
感觉蓝题难度还是有点过了吧?大致思路就是建一个二维数组dp【i】【j】表示从第i个人到第j个人对称的最小次数
这时候就大致可以得出动态转移方程了,如下
1.先设置一个长度l自2至n枚举
2.此时i从1枚举至n-l+1,j此时则为i+l-1。
3.当第i个人颜色等于第j个人时,dp【i】【j】则与dp【i+1】【j-1】相同,赋值;
4.如果不同的话,则为{dp【i+1】【j】,dp【i】【j-1】,dp【i+1】【j-1】}中次数最少的那一个再+1了。
故状态转移方程代码如下:
if(a[i]==a[j]) dp[i][j]=dp[i+1][j-1];//相同情况 else dp[i][j]=min(dp[i+1][j],min(dp[i][j-1],dp[i+1][j-1]))+1;最后输出dp【1】【n】则为正解。
发现了吗?实际上代码很精简的。只要你有心,省选难度在你眼里都将是水题!
PS:初始化会WA第七个点!
#include<bits/stdc++.h> using namespace std; int n,a[3001],dp[3001][3001];//dp[i][j]表示i到j对称的最小次数 int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int l=2;l<=n;l++) for(int i=1;i+l<=n+1;i++)//枚举第i个人 { int j=i+l-1;//枚举第j个人 if(a[i]==a[j]) dp[i][j]=dp[i+1][j-1]; else dp[i][j]=min(dp[i+1][j],min(dp[i][j-1],dp[i+1][j-1]))+1; } cout<<dp[1][n]; }PPS:这是@M_sea dalao給我们讲解的,深入浅出Orz
PPPS:应该没有题解与这个相似吧?因为我们全机房都是听的M_sea dalao讲解的,所以可能机房会有与我相似的题解投上来QAQ
- 1
信息
- ID
- 2784
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者