zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    代码 技术债务 打分
    C++ boost coroutine
    什么是 Python Django Flask &Tornado
    Quartz应用与集群原理分析
    和开源产品对比
    Apache Storm || Processing real-time data
    认清自我,不在迷茫 程序员
    快速傅里叶变换算法
    Netty和Tomcat的区别、性能对比
    HTTP vs. MQTT ->TCP
  • 原文地址:https://www.cnblogs.com/Missa/p/2720419.html
Copyright © 2011-2022 走看看