poj 1925 DP

来源:互联网 发布:php银联在线支付 编辑:程序博客网 时间:2024/05/01 12:05

一开始这道题就没有思路,不知道怎么设状态,所以就推不出来状态转移方程。后来看了一下大牛的博客,原来是对x坐标进行dp。

认真地思考了一下,确实是这样的,这样满足最优子结构,哎,还是思路太窄,要拓展思维啊!

设dp[p[i].x]=min(dp[j]+1)  其中j是比p[i].x小的坐标,并且他们满足约束关系:p[i].y^2>=(p[i].y-p[1].y)^2  +  (p[i].x-j)^2  ;

这样递推下去,一直到p[N].x就ok了。

代码如下:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define MAX 1000100#define INF 0x3f3f3f3fint dp[MAX];struct point{    int x,y;};point p[5005];int N,K,ans;__int64 a,b,c;void DP(){    int i,j;    memset(dp,0x3f,sizeof(dp));    dp[p[1].x]=0;    for(i=2;i<=N;i++)    {        c=p[i].y;        a=p[i].y-p[1].y;        for(j=p[i].x-1;j>=0;j--)        {            b=p[i].x-j;            if(c*c<b*b+a*a) break;            int k=p[i].x+b;            if(k>p[N].x) k=p[N].x;            dp[k]=min(dp[k],dp[j]+1);        }    }    if(dp[p[N].x]==INF) ans=-1;    else ans=dp[p[N].x];}int main(){    int i,j;    scanf("%d",&K);    while(K)    {        scanf("%d",&N);        for(i=1;i<=N;i++)        {            scanf("%d%d",&p[i].x,&p[i].y);        }        DP();        printf("%d\n",ans);        K--;    }    return 0;}


 

0 0