dp最长不下降序列

 1 //
 2 // Created by snnnow on 2020/4/13.
 3 //
 4 //这是dp 问题的基础题
 5 //
 6 //最长不下降
 7 //(导弹拦截是其例题)
 8 //那这篇文章是讲啥呢,
 9 // 主要是吧,这个题是用了二维数组,
10 //而导弹当时是用了三个一维数组
11 //其实本质上是一样的
12 //(有本事干结构体啊!QAQ[手动狗头])
13 
14 //不多说了,ans[i][1]是原数
15 //ans[i][2]是该项的最长
16 //ans[i][3]是指向下一个(下一个值的位置)
17 //开始咯!
18 #include <iostream>
19 using namespace std;
20 int main(){
21     int ans[10010][10];//虽然第二维我们只要三个数,但是还是最好开大一点
22     int n;
23     cin>>n;
24     for (int i = 1; i <= n ; ++i) {
25         cin>>ans[i][1];
26         ans[i][2]=1;
27         ans[i][3]=0;
28 
29     }
30     for (int j = n-1; j >= 1; --j) {
31         int k=0;//注意一个问题,k和p是每次i需要更新的,所以一定放在这个循环这里
32         int p=0;
33         for (int i = j+1; i <= n ; ++i) {
34 
35             if(ans[j][1] >= ans[i][1]  &&  ans[j][2] > k){//k记录的就是所有的ans[j][2]中最大的
36                 k = ans[j][2];
37 
38                 p = j;
39            }
40             if(k>0){
41                 ans[i][3] = p;//p就是个"指针",ans[j][3]存放的就是个位置
42                 ans[i][2] = k+1;
43             }
44 
45         }
46 
47     }
48     //挨个比较一下ans[i][2]就可以找到最大的,注意要找个变量标记出来啊
49     int mark=1;
50     for(int i=1;i <= n;i++){
51         if(ans[i][2] >= ans[mark][2]){
52             mark = i;//这里不是排序,不需要双重循环,只需要找一个东西一直比较着就行
53         }
54     }
55     cout << ans[mark][2]<<endl;
56     while(mark!=0){
57         cout<<" "<<ans[mark][1];
58         mark = ans[mark][3];
59     }
60 return 0;
61 }

这次,把第一个逆序循环--j写成了++j..直接炸了

然后把k的定义写错了位置(k是跟随每一个ans[i]更新的)

太傻了,小白还要继续加油!

猜你喜欢

转载自www.cnblogs.com/zhmlzhml/p/12693160.html