首页 > 其他分享 >[ZJOI2010] 基站选址

[ZJOI2010] 基站选址

时间:2023-11-16 20:36:59浏览次数:35  
标签:min pay ll ZJOI2010 tl 村庄 选址 基站

 我感觉我缺了一个dp优化的思路
我不知道我是不是能够对状态继续优化
dp写少了。。。
确诊了

题目描述

有 NN 个村庄坐落在一条直线上,第 i(i>1)i(i>1) 个村庄距离第 11 个村庄的距离为 DiDi​。需要在这些村庄中建立不超过 KK 个通讯基站,在第 ii 个村庄建立基站的费用为 CiCi​。如果在距离第 ii 个村庄不超过 SiSi​ 的范围内建立了一个通讯基站,那么就村庄被基站覆盖了。如果第 ii 个村庄没有被覆盖,则需要向他们补偿,费用为 WiWi​。现在的问题是,选择基站的位置,使得总费用最小。

输入格式

输入文件的第一行包含两个整数 N,KN,K,含义如上所述。

第二行包含 N−1N−1 个整数,分别表示 D2,D3,⋯ ,DND2​,D3​,⋯,DN​ ,这 N−1N−1 个数是递增的。

第三行包含 NN 个整数,表示 C1,C2,⋯ ,CNC1​,C2​,⋯,CN​。

第四行包含 NN 个整数,表示 S1,S2,⋯ ,SNS1​,S2​,⋯,SN​。

第五行包含 NN 个整数,表示 W1,W2,⋯ ,WNW1​,W2​,⋯,WN​。

输出格式

输出文件中仅包含一个整数,表示最小的总费用。

输入输出样例

输入 #1
3 2
1 2
2 3 2
1 1 0
10 20 30
输出 #1
4

说明/提示

40%的数据中,N≤500N≤500;

100%的数据中,K≤NK≤N,K≤100K≤100,N≤20,000N≤20,000,Di≤1000000000Di​≤1000000000,Ci≤10000Ci​≤10000,Si≤1000000000Si​≤1000000000,Wi≤10000Wi​≤10000。

 人生中第一次写黑题,也是第一次把一道黑题完全理解,也许挺值得庆祝?

裸dp还是很好想的,f[i][j]表示第j个基站建在了i除,其他的建在了1~(i-1)上,此时满足1到i的村子的最小花费
f[i][j]=min(f[k][j-1]+cost(i,k))
j这一维度之和j-1有关,那就是和背包类似的去掉一维,因为对同一个基站不会重复转移,所有不需要倒序
很明显,我们的优化思路就是把每一次求min的操作通过数据结构变为带log的复杂度
那对于一个点i,j,我们要怎么快速计算f[k][j-1]+cost(i,k)的min呢?
如果只是f的内容是非常简单的,但是加上cost就不行了
我们想想cost的内容是什么
我们的i的循环是从后向前的,在前面已经说过了
假设我们的数据结构已经维护好了f[i][j]要用的,那我们现在考虑怎么弄出f[i+1][j]要用的
有什么变化?
i原本是有一个基站的,现在不知道了
假设i+1村庄的影响范围是(L,R),那如果(L,i+1)这个范围没有其他基站了,也就是上一个基站建在了(1,L-1)这个范围,那答案就要加上这个村庄的补偿,再取min,对于之后的所有其他的大于i的状态,这个都是成立的
因为后面的如果要到,肯定当前这个村庄也是要被补偿或者覆盖的嘛,前面的这个位置既然再这个情况下覆盖不到,又没有其他被覆盖的可能,不就是只有补偿了,这是一个可以预计的付出
如果在(L,i-1)这个区间内有,那就不需要,直接取这个区间f数组+pay的min就好了,因为pay=0,所以就是f数组
所以我们的数据结构就需要维护f+pay的min,要支持区间加法
(pay=cost,是一个东西)
所以我们就是直接对每一个j都循环一遍n,然后一边用线段树维护对于当前i的f+pay的最小值来直接转移,最终达到O(nk*log(n))的复杂度

问题就是pay(i,j)怎么维护?而且我们其实讨论的不是i+1处建立基站,而是i+1的影响范围的右边界处
更麻烦了
用建图的方法就好了,可以在总体O(n)的时间内把每一个需要增加的点都遍历到

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll read() {
    char c=getchar();ll a=0,b=1;
    for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
    for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48;return a*b;
}
ll n,d[200001],c[200001],s[200001],w[200001],f[200001],head[200001],ed[200001],st[200001],k,tot;
ll tag[800001],v[800001];
inline ll ls(ll x){
    return (x*2);
}
inline ll rs(ll x){
    return (x*2)+1;
}
struct edge
{
    ll next,to;
}e[800001];
inline void add(ll i,ll j)
{
    e[++tot].next=head[i];
    e[tot].to=j;
    head[i]=tot;
}
void push_down(ll p)
{
    tag[ls(p)]+=tag[p];
    tag[rs(p)]+=tag[p];
    v[ls(p)]+=tag[p];
    v[rs(p)]+=tag[p];
    tag[p]=0;
}
void push_up(ll p)
{
    v[p]=min(v[ls(p)],v[rs(p)]);
}
void build(ll p,ll l,ll r) 
{
    tag[p]=0;
    if(l==r)
    {
        v[p]=f[l];
        return ;
    }
    ll mid=l+((r-l)>>1);
    build(ls(p),l,mid);
    build(rs(p),mid+1,r);
    push_up(p);
}
void update(ll p,ll l,ll r,ll tl,ll tr,ll x)
{
    if(tl>tr)return ;
    if(tl<=l&&r<=tr)
    {
        v[p]+=x;
        tag[p]+=x;
        return ;
    }
    push_down(p);
    ll mid=l+((r-l)>>1);
    if(tl<=mid)update(ls(p),l,mid,tl,tr,x);
    if(tr>mid)update(rs(p),mid+1,r,tl,tr,x);
    push_up(p);
}
ll que(ll p,ll l,ll r,ll tl,ll tr)
{
    if(tl>tr)return 2147483647;
    if(tl<=l&&r<=tr)
        return v[p];
    ll mid=l+((r-l)>>1);
    push_down(p);
    ll Get=2147483647;
    if(tl<=mid)Get=min(Get,que(ls(p),l,mid,tl,tr));
    if(mid<tr)Get=min(Get,que(rs(p),mid+1,r,tl,tr));
    return Get;
}
int main()
{
//    freopen("1.in","r",stdin);
//    freopen("2.out","w",stdout);    
    n=read();k=read();
    for(ll i=2;i<=n;i++)
        d[i]=read();
    for(ll i=1;i<=n;i++)
        c[i]=read();
    for(ll i=1;i<=n;i++)
        s[i]=read();
    for(ll i=1;i<=n;i++)
        w[i]=read();
    n++,k++;d[n]=w[n]=2147483647;//×îºóÒ»¸öµãÒ²²»Ò»¶¨½¨»ùÕ¾£¬»ùÕ¾Ò²²»Ò»¶¨½¨Âú£¬¿ÉÒÔͨ¹ýÕâÖÖ°ì·¨À´¼ÆËã×îÖÕ´ð°¸
    //ËäÈ»ÆäËûµÄ°ì·¨Ò²Ò»Ñù£¬µ«ÕâÖÖ˼·»¹ÊÇºÜºÃµÄ 
    ll now=0;
    for(ll i=1;i<=n;i++)
    {
        st[i]=lower_bound(d+1,d+1+n,d[i]-s[i])-d;
        ed[i]=lower_bound(d+1,d+1+n,d[i]+s[i])-d;
        if(d[ed[i]]>d[i]+s[i])ed[i]--;
        add(ed[i],i);
    }
    for(ll i=1;i<=n;i++)//Ö»ÓÐÒ»¸ö»ùÕ¾ 
    {
        f[i]=now+c[i];
        for(ll u=head[i];u;u=e[u].next)
        {
            ll x=e[u].to;
            now+=w[x];
        }
    }
    ll ans=f[n];
    for(ll ned=2;ned<=k;ned++)
    {
        build(1,1,n);
        for(ll i=1;i<=n;i++)
        {
            f[i]=que(1,1,n,1,i-1)+c[i];
            for(ll j=head[i];j!=0;j=e[j].next)
            {
                ll u=e[j].to;
                update(1,1,n,1,st[u]-1,w[u]);
            }
        }
        ans=min(ans,f[n]);
    }
    cout<<ans<<endl;
    return 0;
}
/*
5 4
2 6 11 16 
10 6 1 7 5 
3 8 6 2 4 
4 4 6 2 7 


*/

这题的代码难度其实不高
但是思考的深度。。
这就是黑题吗
总体的思路是从朴素dp出发的,尝试对朴素dp进行优化
(哪里不行优哪里)
难绷

总体的思路。。。
在我写完之后我分析起来好难啊。。
在我这个上帝视角看来就像是遇到困难就把困难解决
但是我怎么知道我要去解决这个困难而不是换一条路呢?
像是一个拼接的题面,只是单纯的把很多东西套在一起吗
希望我下次遇到这种题面能够做出来

 

标签:min,pay,ll,ZJOI2010,tl,村庄,选址,基站
From: https://www.cnblogs.com/HLZZPawa/p/17834780.html

相关文章

  • 铺先生:如何思考选址才能更好的经营?从经营出发思考问题
    如何思考选址才能更好的经营?给店铺选址是经营前最重要,也是最繁琐的一个环节,在这个环节中,你要思考的问题特别多,这个时候,其实你只需要明白你的出发点是什么就能更好的进行针对性选址了。小编认为这样选址比较好!1. 针对成本选址店铺选址这件事其实是需要很多成本的投入的,不仅仅是门店......
  • 铺先生:给店铺选址有哪些好思路?这些方法可以试一下
    给店铺选址有哪些好思路?很多人在给店铺选址的时候,可能都会围绕着“好”这个点进行入手,虽说不错,但是“好”不一定适合自己!这些朋友在选址思路上就已经陷入了误区!小编认为适合自己的就是“好”!下面小编就给大家提供一些选址思路,帮助大家更好的选择!1. 观察同行在给店铺选址的时候,可以......
  • P2514 [HAOI2010] 工厂选址 题解
    目录DescriptionSolutionCodeDescription有\(m\)座煤矿,每一座煤矿有\(a_i\)吨煤,第\(i\)座煤矿到第\(j\)号发电厂的运费为\(c_{i,j}\)每吨。有一座发电厂(标号为0),需要恰好\(b\)吨煤矿发电,初始运行费用为\(h\)。还有\(n\)座待运行的发电厂(标号为1~n),每座发电厂初......
  • 宏蜂窝基站便携测试设备设计原理图:FMCJ450-基于ADRV9009的双收双发射频FMC子卡
    FMCJ450-基于ADRV9009的双收双发射频FMC子卡一、板卡概述       ADRV9009是一款高集成度射频(RF)、捷变收发器,提供双通道发射器和接收器、集成式频率合成器以及数字信号处理功能。这款IC具备多样化的高性能和低功耗组合,FMC子卡为2路输入,2路输出的射频收发卡,......
  • 铺先生:门店选址要观察什么?都清楚更方便经营
    关于门店选址要观察什么这个问题,一直都是困扰着很多想创业的朋友们的一个问题,但是只要大家多留意那些新门店选择的位置,大家就会发现,其实他们选址观察的因素也都大差不差。其实门店选址是一个需要考虑细节方面的问题,在选址上其实大方向都是一致的。下面就让小编来跟大家说一下那些门......
  • P2602 [ZJOI2010] 数字计数&HDU 2089 (数位dp)
    luoguHDU最近在复习数位dp数位dp,就是在一些计数问题的时候按照一位一位的顺序依次计算,通常可以采用记忆化搜索的方式这两道题就是很典型的数位dp数位dp通常要记录是不是顶着上限,有没有前导零,到了哪一位以及一些特殊的条件要求。数位dp通常要把某个区间的问题转变成两个区间......
  • 服务中心选址
    题目描述一个快递公司希望在一条街道建立新的服务中心。公司统计了该街道中所有区域在地图上的位置,并希望能够以此为依据为新的服务中心选址:使服务中心到所有区域的距离的总和最小。给你一个数组positions,其中positions=[left,right]表示第i个区域在街道上的位置其中left代......
  • 截至 7 月底,我国 5G 基站累计达到 305.5 万个
    截至7月底,我国5G基站累计达到305.5万个来源:投稿作者: NewsBot2023-09-0311:36:49 29月2日,2023年中国国际服务贸易交易会数字贸易发展趋势和前沿高峰论坛在北京举办。工业和信息化部总工程师赵志国近日出席论坛活动并致辞称,近年来我国扎实推动数字......
  • 铺先生:店铺选址要警惕的点,内行人才知道
    要想店铺经营好,店铺选址要谨慎。想开店就得先找到合适的场地,一般有经验的内行人都会通过一些细节判断来让自己提高找到好地址的概率。但是其中一些点,需要谨慎对待,否则可能适得其反。下面就让小编给大家讲讲店铺选址要警惕的点。1. 预算合理使用我们不管是做什么事情,在行动之前一......
  • 铺先生:广州开店选址细节,帮助大家找到合适的地址
    在广州这座美丽的一线大都市中,有着很多的朝九晚五的打工人,他们厌倦了打工的生活,想着找到一个合适的地址开一家属于自己的店铺。可是,自己对于开店选址这件事并不是很了解,不知道广州开店选址细节都有社什么。那么小编就针对这个问题,说一下看法,帮助大家排忧解难。1. 看街口类型我们......