zoukankan      html  css  js  c++  java
  • [bzoj3437]小P的牧场

    题面在这里

    题意

    (n)个牧场,自西向东呈一字形排列,需要控制这些牧场,
    每个牧场上可以花费(a_i)的费用建立一个控制站,
    每个控制站控制的牧场是它所在的牧场一直到它西边第一个控制站之前的所有牧场,每个牧场(i)的放养量是(b_i),求最小总费用

    数据范围

    [1le nle10^5, 0 <a_i,b_ile10^4 ]

    sol

    不出意外的话应该是斜率(DP)最后一道入门题了
    (f[i])表示在第(i)个牧场建立一个控制站并控制之前所有牧场的最小费用,有

    [f[i]=min_{j=0}^{i-1}(f[j]+sum_{k=j+1}^{i}b[k](i-k)+a[i]) ]

    (c[i]=sum_{j=1}^{i}(b[j] imes j))(d[i]=sum_{j=1}^{i}b[j]),有

    [=min_{j=0}^{i-1}(f[j]-sum_{k=j+1}^{i}(b[k] imes k)+i imessum_{k=j+1}^{i}b[k]+a[i]) ]

    [=min_{j=0}^{i-1}(f[j]-(c[i]-c[j])+i imes(d[i]-d[j])+a[i]) ]

    [=min_{j=0}^{i-1}(f[j]+c[j]-i imes d[j])+a[i]+i imes d[i]-c[i] ]

    斜率优化,插点((d[j],f[j]+c[j])),询问递增斜率(k_i=i)

    代码

    #include<bits/stdc++.h>
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<iomanip>
    #include<cstring>
    #include<complex>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #define mp make_pair
    #define pub push_back
    #define puf push_front
    #define pob pop_back
    #define pof pop_front
    #define RG register
    #define il inline
    using namespace std;
    typedef unsigned long long ull;
    typedef vector<int>VI;
    typedef long long ll;
    typedef double dd;
    const dd eps=1e-10;
    const int mod=1e8;
    const int N=1000010;
    il ll read(){
    	RG ll data=0,w=1;RG char ch=getchar();
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
    	return data*w;
    }
    
    il void file(){
    	freopen(".in","r",stdin);
    	freopen(".out","w",stdout);
    }
    
    ll n,a[N],b[N],c[N],d[N],f[N];
    struct node{ll x,y;}Q[N];ll L=1,R;
    il void insert(node q){
    	while(L<R&&(Q[R].y-Q[R-1].y)*(q.x-Q[R].x)>=(q.y-Q[R].y)*(Q[R].x-Q[R-1].x))R--;
    	Q[++R]=q;
    }
    il ll query(ll k){
    	while(L<R&&k*(Q[L+1].x-Q[L].x)>=Q[L+1].y-Q[L].y)L++;
    	return Q[L].y-k*Q[L].x;
    }
    
    int main()
    {
    	n=read();
    	for(RG int i=1;i<=n;i++)a[i]=read();
    	for(RG int i=1;i<=n;i++){
    		b[i]=read();c[i]=c[i-1]+b[i]*i;d[i]=d[i-1]+b[i];
    	}
    
    	insert((node){0,0});
    	for(RG int i=1;i<=n;i++){
    		f[i]=query(i)+a[i]+i*d[i]-c[i];
    		insert((node){d[i],f[i]+c[i]});
    	}
    
    	printf("%lld
    ",f[n]);
    	
    	return 0;
    }
    
    
  • 相关阅读:
    【题解】 bzoj1207: [HNOI2004]打鼹鼠 (动态规划)
    【题解】 bzoj1088: [SCOI2005]扫雷Mine (神奇的做法)
    【题解】 bzoj4472: [Jsoi2015]salesman (动态规划)
    【题解】 bzoj4033: [HAOI2015]树上染色* (动态规划)
    【题解】 [HNOI/AHOI2018]道路 (动态规划)
    炫酷的英文字体分享
    艾伦·麦席森·图灵
    历史上最知名的15位计算机科学家
    浏览器首页被改为2345之解决方法
    linux命令缩写及全称
  • 原文地址:https://www.cnblogs.com/cjfdf/p/8653629.html
Copyright © 2011-2022 走看看