poj 1160 dp
题意:n个村庄建p个邮局,最短距离和。
dp[MAXN][35];//dp[i][j]表示前i个村庄有j个post且第i个村庄有post的最小值
优化前(969ms....):
View Code
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 7 using namespace std; 8 9 #define MAXN 310 10 #define Max(x,y) (x>y?x:y) 11 #define Min(x,y) (x>y?y:x) 12 #define inf 0x7ffffff 13 int dp[MAXN][35];//dp[i][j]表示前i个村庄有j个post且第i个村庄有post的最小值 14 int dis[MAXN][MAXN];//dis[i][j]第i个村庄j距离 15 int vx[MAXN]; 16 int v,p; 17 18 int main() 19 { 20 while(scanf("%d%d",&v,&p) != EOF) 21 { 22 for(int i=1;i<=v;i++) 23 scanf("%d",&vx[i]); 24 vx[v+1]=vx[v]*(v+1); 25 for(int i=1;i<=v+1;i++) 26 for(int j=1;j<=v+1;j++) 27 if(i==j) 28 dis[i][j]=0; 29 else 30 dis[i][j]=Max(vx[i],vx[j])-Min(vx[i],vx[j]); 31 //----------------------------- 32 //for(int i=1;i<=v+1;i++) 33 // for(int j=1;j<=v+1;j++) 34 // cout<<dis[i][j]<<endl; 35 //----------------------------- 36 for(int i=0;i<=v+1;i++) 37 for(int j=0;j<=p+1;j++) 38 dp[i][j]=inf; 39 for(int i=1;i<=v+1;i++) 40 for(int j=i;j<=33;j++) 41 dp[i][j]=0; 42 for(int i=2;i<=v+1;i++) 43 dp[i][1]=dp[i-1][1]+dis[i-1][i]*(i-1); 44 for(int k=2;k<=p+1;k++) 45 { 46 for(int i=k+1;i<=v+1;i++) 47 { 48 for(int j=k-1;j<i;j++) 49 { 50 int tmp=dp[j][k-1]; 51 for(int w=j+1;w<i;w++) 52 tmp+=Min(dis[j][w],dis[w][i]); 53 dp[i][k]=Min(dp[i][k],tmp); 54 //if(k==p+1 && i==v+1) 55 // cout<<tmp<<endl; 56 } 57 } 58 } 59 printf("%d\n",dp[v+1][p+1]); 60 } 61 return 0; 62 }
优化后:
View Code
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 7 using namespace std; 8 9 #define MAXN 310 10 #define Max(x,y) (x>y?x:y) 11 #define Min(x,y) (x>y?y:x) 12 #define inf 0x7ffffff 13 int dp[MAXN][35];//dp[i][j]表示前i个村庄有j个post且第i个村庄有post的最小值 14 int dis[MAXN][MAXN];//dis[i][j]第i个村庄j距离 15 int vx[MAXN]; 16 int sum[MAXN][MAXN];//min[i][j]为i,j有post时,i,j中间的点的最小距离和 17 int v,p; 18 19 int main() 20 { 21 while(scanf("%d%d",&v,&p) != EOF) 22 { 23 for(int i=1;i<=v;i++) 24 scanf("%d",&vx[i]); 25 vx[v+1]=vx[v]*(v+1); 26 for(int i=1;i<=v+1;i++) 27 for(int j=1;j<=v+1;j++) 28 if(i==j) 29 dis[i][j]=0; 30 else 31 dis[i][j]=Max(vx[i],vx[j])-Min(vx[i],vx[j]); 32 //----------------------------- 33 //for(int i=1;i<=v+1;i++) 34 // for(int j=1;j<=v+1;j++) 35 // cout<<dis[i][j]<<endl; 36 //----------------------------- 37 for(int i=0;i<=v+1;i++) 38 for(int j=0;j<=p+1;j++) 39 dp[i][j]=inf; 40 for(int i=1;i<=v+1;i++) 41 for(int j=i;j<=33;j++) 42 dp[i][j]=0; 43 for(int i=2;i<=v+1;i++) 44 dp[i][1]=dp[i-1][1]+dis[i-1][i]*(i-1); 45 for(int i=1;i<=v+1;i++) 46 for(int j=i;j<=v+1;j++) 47 { 48 sum[i][j]=0; 49 for(int k=i+1;k<j;k++) 50 sum[i][j]+=Min(dis[i][k],dis[k][j]); 51 } 52 for(int k=2;k<=p+1;k++) 53 { 54 for(int i=k+1;i<=v+1;i++) 55 { 56 for(int j=k-1;j<i;j++) 57 { 58 int tmp=dp[j][k-1]+sum[j][i]; 59 dp[i][k]=Min(dp[i][k],tmp); 60 //if(k==p+1 && i==v+1) 61 // cout<<tmp<<endl; 62 } 63 } 64 } 65 printf("%d\n",dp[v+1][p+1]); 66 } 67 return 0; 68 }