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

深海鱼的眼泪
**搬运于
2025-08-24 21:24:46,当前版本为作者最后更新于2017-05-22 21:00:38,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
如楼下所说,下面两个题解是有反例的,如输入数据为 6 1 2 3 4 5 1 时就不行了。
然而数据弱呀╮(╯▽╰)╭
那么这个题解的思路显然不是我自己的
http://blog.csdn.net/nike0good/article/details/8605219
【蒟蒻表示花了很久看懂大神的题解……】
在前i位中找长j位的以第i位结尾的上升子序列,并且剩下的也是上升子序列,那么f[i][j]表示剩下的(即前i位中长i-j位的不以第i位结尾的)上升子序列的最后一位的最小值。
然后转移:
如果a[i]<a[i+1],那么f[i+1][j+1]=min(f[i+1][j+1],f[i][j]),相当于可以直接把f[i][j]扩展到第i+1位。
如果f[i][j]<a[i+1],那么f[i+1][i-j+1]=min(f[i+1][i-j+1],a[i]),相当于第i+1继承前i位中i-j位长的上升子序列。
#include <iostream> #include <cstdio> #include <cstring> #define INF (2139062143) using namespace std; void read(int& x){ x=0; int y=1; char ch=getchar(); while (ch<'0'||ch>'9'){ if (ch=='-') y=-1; ch=getchar(); } while (ch>='0'&&ch<='9'){ x=x*10+ch-'0'; ch=getchar(); } x=x*y; } int n,a[2001],f[2001][2001]; int main(){ int i,j; while (~scanf("%d",&n)){ memset(f,127,sizeof(f)); for (i=1;i<=n;++i){ read(a[i]); } f[1][1]=-1; for (i=1;i<=n;++i){ for (j=1;j<=i;++j){ if (f[i][j]!=INF){ if (a[i]<a[i+1]) if (f[i+1][j+1]>f[i][j]) f[i+1][j+1]=f[i][j]; if (f[i][j]<a[i+1]) if (f[i+1][i+1-j]>a[i]) f[i+1][i+1-j]=a[i]; } } } if (f[n][n/2]==INF) printf("No!\n"); else printf("Yes!\n"); } return 0; }
- 1
信息
- ID
- 404
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者