poj 1160 Post Office (dp + wqs half)

The meaning of problems

There are post offices p, n villages, post offices can only be built in the village,

Seeking to send a letter so that all distance and minimum values. ,

 

SOLUTION:

First of dp can n3

dp i, j represent the i-th place before the establishment of minimum cost j a post office,

In the process at an arbitrary interval to establish a post office is a minimum cost (an interval put a post office, then placed in a median position most)

 

Thinking about how to optimize dp

eliminate the one-dimensional binary wqs

Set f (x) = g (x) + kx, each set up a post office should increase the value of k, look at the current f (x) is taken to the maximum and the relationship between x and p of questions asked

 

CODE:

#include <iostream>

#include <algorithm>

#include <cstring>

#include <cstdio>

#include <cmath>

#include <set>

#include <map>

#include <vector>

#include <stack>

#include <queue>

#include <functional>

const int INF=0x3f3f3f3f;

const int maxn=300+10;

const int mod=1e9+7;

const int MOD=998244353;

const double eps=1e-7;

typedef long long ll;

#define vi vector<int>

#define si set<int>

#define pii pair<int,int>

#define pi acos(-1.0)

#define pb push_back

#define mp make_pair

#define lowbit(x) (x&(-x))

#define sci(x) scanf("%d",&(x))

#define scll(x) scanf("%lld",&(x))

#define sclf(x) scanf("%lf",&(x))

#define pri(x) printf("%d",(x))

#define rep(i,j,k) for(int i=j;i<=k;++i)

#define per(i,j,k) for(int i=j;i>=k;--i)

#define mem(a,b) memset(a,b,sizeof(a))

using namespace std;

//dp[i][j]代表前i个村庄 需要j个邮局的最小花费

//

int n,p,a[maxn],sum[maxn],dis[maxn][maxn];
int c[maxn];
int dp[maxn];
inline int check(int mid)
{
    for(int i=1;i<=n;i++)
        dp[i]=1e16;
    dp[0]=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=i;j++)
        {
            if(dp[i]>dp[j-1] + dis[j][i] + mid)
            {
                dp[i]=dp[j-1] + dis[j][i] + mid;
                c[i]=c[j-1]+1;
            }
        }
    }
    //for(int i=1;i<=n;i++)cout<<dp[i]<<" ";cout<<endl;
    return c[n];
}
void work()
{
    int l=-1e9,r=1e9;int ans=0;
    while(l<=r)
    {
        int mid=l+r>>1;
        if(check(mid)<=p)ans=mid,r=mid-1;
        else l=mid+1;
      //  cout<<mid<<" "<<check(mid)<<endl;
    }
    check(ans);
    long long t = dp[n] - p*ans;
    cout<<t<<endl;
}
int main()

{

    while(~scanf("%d%d",&n,&p))

    {

        REP (I,. 1, n-) SCI (A [I]); 

        Sort (A +. 1, A + n-+. 1); 

        SUM [0] = 0; 

        REP (I,. 1, n-) SUM [I] = SUM [I-. 1] + A [I]; 

        REP (I,. 1, n-) 

        { 

            DIS [I] [I] = 0; 

            REP (J, I +. 1, n-) 

            { 

                int MID = (I + J) / 2; 

                // coordinate origin of the drawing can move to prove a [mid] each prefix and adding Finally understood as a [mid] 

                @ SUM [J] -sum [MID] to [mid + 1, j] summing, sum [mid-1] -sum [i-1] to [i, mid-1] summation 

                dis [i] [j] = (sum [j] -sum [mid]) - (j -mid) * A [MID] + (MID-I) * A [MID] - (SUM [-MID. 1] -sum [-I. 1]); 

            } 

        } 

        Work (); 


    } 

    return 0; 

}

  

 

Guess you like

Origin www.cnblogs.com/zhangbuang/p/11236340.html