poj1741,poj 1160 dp

 2023-10-18 阅读 30 评论 0

摘要:題意: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 #i

題意: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 }

轉載于:https://www.cnblogs.com/Missa/archive/2012/10/11/2720419.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/148029.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息