http://acm.hdu.edu.cn/showproblem.php?pid=4205
有很多船要停在自己的家前面,船长的船一定要停在家门口中间,输出最多多少个船在家门口。
dp[i][j]=min(dp[i-1][j] , if(dp[i-1][j-1]<=w[i].x) max(dp[i-1][j-1]+w[i].li,w[i].x) ) 。。。
碰到船长的船是固定的。
View Code
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 #include <stdlib.h> 6 using namespace std; 7 #define N 1010 8 #define inf 2000000010 9 struct node{ 10 int x,li,id; 11 }w[N]; 12 bool cmp(const node &a,const node &b){ 13 if(a.x!=b.x) return a.x<b.x; 14 return a.li>b.li; 15 } 16 int dp[N][N]; 17 int main(){ 18 int T,n,id; 19 scanf("%d",&T); 20 while(T--){ 21 scanf("%d",&n); 22 int Min=-inf; 23 for(int i=0;i<n;++i){ 24 scanf("%d%d",&w[i].x,&w[i].li); 25 w[i].id=i; 26 } 27 sort(w,w+n,cmp); 28 for(int i=0;i<n;++i){ 29 if(!w[i].id) id=i; 30 for(int j=0;j<=n;++j) 31 dp[i][j]=inf; 32 } 33 if(id){ 34 dp[0][0]=Min; 35 dp[0][1]=w[0].x; 36 } 37 else dp[0][1]=w[0].x+(w[0].li+1>>1); 38 for(int i=1;i<n;++i){ 39 if(i==id){ 40 int l=w[i].x-(w[i].li+1>>1); 41 int r=w[i].x+(w[i].li+1>>1); 42 for(int j=0;j<=i;++j) 43 if(dp[i-1][j]<=l) 44 dp[i][j+1]=r; 45 continue; 46 } 47 for(int j=0;j<=i;++j){ 48 dp[i][j]=min(dp[i][j],dp[i-1][j]); 49 if(dp[i-1][j]!=inf){ 50 if(dp[i-1][j]<=w[i].x){ 51 int temp=max(dp[i-1][j]+w[i].li,w[i].x); 52 dp[i][j+1]=min(dp[i][j+1],temp); 53 } 54 } 55 } 56 } 57 for(int i=n;i;--i) 58 if(dp[n-1][i]!=inf){ 59 printf("%d\n",i); 60 break; 61 } 62 } 63 return 0; 64 }