标签:
vijosP1006 晴天小猪历险记之Hill
【思路】
图上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 }
标签:
原文地址:http://www.cnblogs.com/lidaxin/p/4899866.html