挖地雷——线性dp

P2196 [NOIP1996 提高组] 挖地雷 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

 

刚开始想的是记忆化搜索,但是发现这个问题是一维的,用记忆化搜索会麻烦,所以用线性dp。

 

状态表示:走到第i个地窖后的地雷最大总数量。(以终点作为状态表示,遍历前i-1个)

状态计算: f [ i ] = m a x (  f [ 1 ] , f [2 ] ,  .. .  ,f [ i - 1 ] )  +a  [ i ] 与  f[ i ] 本身求最大值

 

新知识:如何正向输出路径:用递归。

注意不是return shuchu(pre[x])

void shuchu(int x)
{
    if(pre[x]) shuchu(pre[x]);
    printf("%d ",x);
}

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N=25;
 4 int f[N],a[N],pre[N];
 5 bool st[N][N];
 6 int n;
 7 
 8 void shuchu(int x)
 9 {
10     if(pre[x]) shuchu(pre[x]);
11     printf("%d ",x);
12 }
13 
14 int main()
15 {
16     scanf("%d",&n);
17     for(int i=1;i<=n;i++)
18     {
19         scanf("%d",&a[i]);
20         f[i]=a[i];
21     }
22     for(int i=1;i<=n-1;i++)
23         for(int j=i+1;j<=n;j++)
24             scanf("%d",&st[i][j]);
25         
26     int ans=0,pos=0;
27     for(int i=2;i<=n;i++)
28     {
29         for(int j=1;j<=i-1;j++)
30         {
31             if(st[j][i]&&f[i]<f[j]+a[i])
32             {
33                 f[i]=f[j]+a[i];
34                 pre[i]=j;
35             }
36         }
37         if(ans<f[i])
38         {
39             ans=f[i];
40             pos=i;
41         }
42     }
43     
44     shuchu(pos);
45     printf("\n%d\n",ans);
46     return 0;
47 }
View Code

 

posted @ 2022-03-30 15:04  wellerency  阅读(36)  评论(0编辑  收藏  举报