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 }