vijosP1006 晴天小猪历险记之Hill

vijosP1006 晴天小猪历险记之Hill

 

链接:https://vijos.org/p/1006

 

【思路】

   图上DP。

   这个题的递推顺序是关键。先从上一行得到最小值,然后从本行比较最小值,注意本行、本行与上一行之间的第一段与最后一段是相通的。

 

【代码】

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
 5 using namespace std;
 6 
 7 const int maxn  = 1000+10;
 8 const int INF=1<<30;
 9 
10 int w[maxn][maxn],d[maxn][maxn];
11 int n;
12 
13 int main() 
14 {
15      scanf("%d",&n);
16      FOR(i,1,n) FOR(j,1,i) scanf("%d",&w[i][j]);
17      memset(d,25,sizeof(d));
18      d[n][0]=0;
19      FOR(i,1,n) d[n][i]=d[n][i-1]+w[n][i];
20      for(int i=n-1;i;i--)
21      {
22          FOR(j,1,i) {
23              if(j==1) 
24                  d[i][j]=min(d[i+1][i+1],min(d[i+1][j],d[i+1][j+1]))+w[i][j];
25              else if(j==i) {
26                   d[i][j]=min(d[i+1][1],min(d[i+1][j],d[i+1][j+1]))+w[i][j];     
27              }
28              else 
29                    d[i][j]=min(d[i+1][j],d[i+1][j+1]) + w[i][j];
30          }
31          d[i][1] = min(d[i][1],d[i][i]+w[i][1]); 
32         FOR(j,2,i) d[i][j] = min(d[i][j],d[i][j-1] + w[i][j]);
33         for(int j=i-1;j;j--) d[i][j] = min(d[i][j],d[i][j+1] + w[i][j]);
34      }
35      printf("%d\n",d[1][1]);
36      return 0;
37 }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值