标签:poj 3042 grazing on the run a long linear field 区间dp
区间dp,~~~~
dp[i][j][0]表示i到j之间已经走过,并且现在在i点的staleness(可以理解为枯萎指数)最小值,
dp[i][j][1]表示i到j之间已经走过,并且现在在j点的staleness最小值。
于是对于在i点,可能从i+1->i,也可能从j->i,即:
很重要的一点,在我们转移到i时,除了即将到达的i点,还有未到达的(n-(j-i+1))个点,即总共(n-(j-i))个点,它们的枯萎指数均在增加,so~
dp[i][j][0]=min(dp[i+1][j][0]+(n-(j-i))*(pos[i+1]-pos[i]),dp[i+1][j][1]+(n-(j-i))*(pos[j]-pos[i]));
同理对于当前在j点,也可以得到向相应的方程:
dp[i][j][1]=min(dp[i][j-1][1]+(n-(j-i))*(pos[j]-pos[j-1),dp[i][j-1][0]+(n-(j-i))*(pos[j]-pos[i])).
最后需要注意的就是初始话的问题了,找到L在原序列中的位置就好。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
题目链接:http://poj.org/problem?id=3042
#include<cstdio> #include<cstring> #include<algorithm> #define N 1000+10 using namespace std; int p[N]; int f[N][N][2]; int main() { int n,s; while(~scanf("%d%d",&n,&s)) { int ok=1; for(int i=0;i<n;i++) { scanf("%d",&p[i]); if(p[i]==s) ok=0; //可能存在某点与起点重合的情况。 } if(ok) p[n++]=s; sort(p,p+n); int pos=lower_bound(p,p+n,s)-p; //二分查找L的位置。 memset(f,0x3f,sizeof(f)); f[pos][pos][0]=f[pos][pos][1]=0; //起点~ for(int i=pos;i>=0;i--) { for(int j=pos;j<n;j++) { f[i][j][0]=min(f[i][j][0],f[i+1][j][0]+(n-(j-i))*(p[i+1]-p[i])); f[i][j][0]=min(f[i][j][0],f[i+1][j][1]+(n-(j-i))*(p[j]-p[i])); f[i][j][1]=min(f[i][j][1],f[i][j-1][1]+(n-(j-i))*(p[j]-p[j-1])); f[i][j][1]=min(f[i][j][1],f[i][j-1][0]+(n-(j-i))*(p[j]-p[i])); } } printf("%d\n",min(f[0][n-1][0],f[0][n-1][1])); } return 0; }
POJ 3042 Grazing on the Run (区间DP),布布扣,bubuko.com
POJ 3042 Grazing on the Run (区间DP)
标签:poj 3042 grazing on the run a long linear field 区间dp
原文地址:http://blog.csdn.net/darwin_/article/details/38701825