HDU4362(dp)两种算法

http://acm.hdu.edu.cn/showproblem.php?pid=4362

dp[i][j]=min{dp[i-1][k]+abs(arr[i][j].x-arr[i-1][k].x)+arr[i][j].w}

1、优先队列法:

  1 #include <iostream>
  2 #include <cstring>
  3 #include <queue>
  4 #include <algorithm>
  5 #include <cstdio>
  6 using namespace std;
  7 const int Ni = 1005;
  8 const int inf=1<<27;
  9 struct node{
 10     int x,w;
 11     bool operator < (const node &a) const
 12     {
 13         return x<a.x;
 14     }
 15 }arr[52][Ni];
 16 struct qnode{
 17     int val,x;
 18     bool operator < (const qnode &a) const
 19     {
 20         if(val>a.val) return 1;
 21         if(val==a.val&&x>a.x) return 1;
 22         return 0;
 23     }
 24 };
 25 int dp[52][Ni];
 26 int n,m;
 27 inline void cInit()
 28 {
 29     int i,j;
 30     for(i=0;i<n;i++)
 31     {
 32         for(j=0;j<m;j++)
 33         {
 34             scanf("%d",&arr[i][j].x);
 35         }
 36     }
 37     for(i=0;i<n;i++)
 38     {
 39         for(j=0;j<m;j++)
 40         {
 41             scanf("%d",&arr[i][j].w);
 42         }
 43     }
 44     for(i=0;i<n;i++)
 45     {
 46         sort(arr[i],arr[i]+m);
 47     }
 48 }
 49 int main()
 50 {
 51     int cs,x,i,j,ans;
 52     cin>>cs;
 53     while(cs--)
 54     {
 55         scanf("%d%d%d",&n,&m,&x);
 56         cInit();
 57         for(j=0;j<m;j++)
 58         {
 59             dp[0][j]=x-arr[0][j].x;
 60             if(dp[0][j]<0) dp[0][j]=-dp[0][j];
 61             dp[0][j]+=arr[0][j].w;
 62         }
 63         for(i=1;i<n;i++)
 64         {
 65             priority_queue<qnode> ql,qr;
 66             qnode qn;
 67             for(j=0;j<m;j++)
 68             {
 69                 qn.val=dp[i-1][j]+arr[i-1][j].x;
 70                 qn.x=arr[i-1][j].x;
 71                 qr.push(qn);
 72             }
 73             int k=0;
 74             for(j=0;j<m;j++)
 75             {
 76                 dp[i][j]=inf;
 77                 while(k<m&&arr[i-1][k].x<=arr[i][j].x)
 78                 {
 79                     qn.val=dp[i-1][k]-arr[i-1][k].x;
 80                     qn.x=arr[i-1][k].x;
 81                     ql.push(qn);
 82                     k++;
 83                 }
 84                 if(!ql.empty())
 85                 {
 86                     qn=ql.top();
 87                     dp[i][j]=min(dp[i][j],qn.val+arr[i][j].x+arr[i][j].w);
 88                 }
 89                 if(!qr.empty())
 90                 {
 91                     qn=qr.top();
 92                     while(!qr.empty()&&qn.x<arr[i][j].x)
 93                     {
 94                         qr.pop();
 95                         qn=qr.top();
 96                     }
 97                     if(qn.x>=arr[i][j].x)
 98                     dp[i][j]=min(dp[i][j],qn.val-arr[i][j].x+arr[i][j].w);
 99                 }
100             }
101         }
102         ans=inf;
103         for(i=0;i<m;i++)
104         {
105             if(ans>dp[n-1][i])
106                 ans=dp[n-1][i];
107         }
108         printf("%d\n",ans);
109     }
110     return 0;
111 }

2、二分法:

  1 #include <iostream>
  2 #include <cstring>
  3 #include <queue>
  4 #include <algorithm>
  5 #include <cstdio>
  6 using namespace std;
  7 const int Ni = 1005;
  8 const int inf=1<<27;
  9 struct node{
 10     int x,w;
 11     bool operator < (const node &a) const
 12     {
 13         return x<a.x;
 14     }
 15 }arr[52][Ni];
 16 int dp[52][Ni];
 17 int n,m;
 18 inline void cInit()
 19 {
 20     int i,j;
 21     for(i=0;i<n;i++)
 22     {
 23         for(j=0;j<m;j++)
 24         {
 25             scanf("%d",&arr[i][j].x);
 26         }
 27     }
 28     for(i=0;i<n;i++)
 29     {
 30         for(j=0;j<m;j++)
 31         {
 32             scanf("%d",&arr[i][j].w);
 33         }
 34     }
 35     for(i=0;i<n;i++)
 36     {
 37         sort(arr[i],arr[i]+m);
 38     }
 39 }
 40 int finds(int i,int l,int r,int key)
 41 {
 42     int mid;
 43     while(l<=r)
 44     {
 45         mid=(l+r)>>1;
 46         if(arr[i][mid].x>key) r=mid-1;
 47         else l=mid+1;
 48     }
 49     return r;
 50 }
 51 int mil[Ni],mir[Ni];
 52 int main()
 53 {
 54     int cs,x,i,j,ans;
 55     cin>>cs;
 56     while(cs--)
 57     {
 58         scanf("%d%d%d",&n,&m,&x);
 59         cInit();
 60         for(j=0;j<m;j++)
 61         {
 62             dp[0][j]=x-arr[0][j].x;
 63             if(dp[0][j]<0) dp[0][j]=-dp[0][j];
 64             dp[0][j]+=arr[0][j].w;
 65         }
 66         for(i=1;i<n;i++)
 67         {
 68             int mi=inf;
 69             for(j=0;j<m;j++)
 70             {
 71                 mi=min(mi,dp[i-1][j]-arr[i-1][j].x);
 72                 mil[j]=mi;
 73             }
 74             mi=inf;
 75             for(j=m-1;j>=0;j--)
 76             {
 77                 mi=min(mi,dp[i-1][j]+arr[i-1][j].x);
 78                 mir[j]=mi;
 79             }
 80             for(j=0;j<m;j++)
 81             {
 82                 dp[i][j]=inf;
 83                 if(arr[i][j].x<=arr[i-1][0].x)
 84                 dp[i][j]=min(dp[i][j],mir[0]-arr[i][j].x+arr[i][j].w);
 85                 else if(arr[i][j].x>=arr[i-1][m-1].x)
 86                 dp[i][j]=min(dp[i][j],mil[m-1]+arr[i][j].x+arr[i][j].w);
 87                 else
 88                 {
 89                     int r=finds(i-1,0,m-1,arr[i][j].x);
 90                     dp[i][j]=min(dp[i][j],mil[r]+arr[i][j].x+arr[i][j].w);
 91                     dp[i][j]=min(dp[i][j],mir[r+1]-arr[i][j].x+arr[i][j].w);
 92                 }
 93             }
 94         }
 95         ans=inf;
 96         for(i=0;i<m;i++)
 97         {
 98             if(ans>dp[n-1][i])
 99                 ans=dp[n-1][i];
100         }
101         printf("%d\n",ans);
102     }
103     return 0;
104 }

 

posted @ 2012-08-15 15:40  qijinbiao1  阅读(378)  评论(0编辑  收藏  举报