zoukankan      html  css  js  c++  java
  • 1160Post Office

    我的代码超时了,用太多for了

    #include "iostream"
    #define INF 10000000;
    using namespace std;
    int min(int a,int b){return a>b?b:a;}
    
    int main(){
      int n,m,num[320],v,i,j,k,sum,g[320][320],l,dp[320][320];
      while(cin>>n>>m){
        for(i=1;i<=n;i++)cin>>num[i];
    
        for(v=0;v<n;v++){
          for(i=1;i<=n-v;i++){
            j=i+v;
            g[i][j]=INF;
            for(k=i;k<=j;k++){
              sum=0;
              for(l=i;l<=j;l++){
                sum+=(num[k]-num[l]>0?num[k]-num[l]:num[l]-num[k]);
              }
              g[i][j]=min(g[i][j],sum);
            }
          }
        }
        for(i=1;i<=n;i++)dp[i][1]=g[1][i];
        for(i=2;i<=m;i++){
          for(j=i;j<=n;j++){
            dp[j][i]=INF;
            for(k=j-1;k>=i-1;k--){
              dp[j][i]=min(dp[j][i],dp[k][i-1]+g[k+1][j]);
            }
          }
        }
       cout<<dp[n][m]<<endl;
      }
    }

    看看人家AC的代码吧,其实有些规律的

    区间dp[m][n]表示前面n个点设m个邮局,最后一个可以不放。

    那么状态方程dp[m][n] = min{dp[m-1][t] + s[t+1][n] } 

    s[t][n]表示在t到n站间设立一个邮局所能达到的最小和。

    通过观察发现|xi-xr|+|xn+1-i-xr|>=|xi-xn+1-i|. xr为邮局所在位子

    那么|xi-xr|+|xi+1-xr| +....|xn-xr| >= |xn-xi|+|xn-1-xi+1|..

    当xr=x(i+n)/2 等号成立

    最后可以写成 S[a,b]=S[a,b-1]+S[b]-x[(a+b)/2]

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    #define MX 310
    int dp[32][MX],sum[MX][MX];
    int P[MX];
    int N , V;
    
    
    
    int main(){
        int i , j , p ,k;
        scanf("%d %d", &N, &V);
        for(i=0 ; i<N ; i++)
            scanf("%d" , &P[i+1] );
    
        for(i=1 ; i< N ; i++){
            for(j=i+1 ; j<= N ; j++){
                sum[i][j] = sum[i][j-1]+  P[j]  -  P[(i+j) / 2];
                if(i==1)
                    dp[1][j] = sum[i][j];
            }
        }
    
        for(i=2; i<=V ; i++)
        {
            for(j=i+1 ; j<=N ; j++)
            {
                dp[i][j] = 0x7FFFFFFF;
                for(k=i-1 ; k<=j-1; k++)
                {
                    dp[i][j] = min( dp[i][j] , dp[i-1][k] + sum[k+1][j] );
                }
            }
        }
    
        printf("%d
    " , dp[V][N]);
        return 0;
    }
  • 相关阅读:
    什么是多线程中的上下文切换?
    java 中有几种方法可以实现一个线程?
    什么叫线程安全?servlet 是线程安全吗?
    什么是线程调度器(Thread Scheduler)和时间分片(Time Slicing )?
    一个线程运行时发生异常会怎样?
    我的样式
    springboot+dynamic多数据源配置
    mybatis plus条件拼接
    springboot配置虚拟路径
    springboot+mybatis+Druid配置多数据源(mysql+postgre)
  • 原文地址:https://www.cnblogs.com/dowson/p/3285869.html
Copyright © 2011-2022 走看看