cf 1216f

news/2024/11/17 21:45:31/

https://codeforc.es/problemset/problem/1216/F

 

有直线上n个位置,每个位置上可以花费i的代价使得联网,某些位置可以放置路由器,放路由器的代价也是i,放置了路由器以后,可以让[i-k,i+k]的范围内上网,要求每台电脑都可以上网,最少需要多少代价。 

 

思路: 动态规划+贪心+线段树维护 

 

f[i]表示前i个电脑上网所需要的最小费用。  

转移的时候分为两种情况。  

1. 第i台电脑独立上网,花费的代价是i

f[i-1]+i 

2 第i台电脑通过前面某台电脑的路由器上网,根据贪心的原则,肯定是在[i-k,i-1]里面位置最小的可以放路由器的地方,一来覆盖的范围可以更大,二来费用更低。  

我们可以通过线段树里面维护这个位置,二分来查找。

转移的时候,注意由于区间可以重叠,所以我们要求一个区间最小值来进行转移,还是用线段树来做。  

 1 #include<bits/stdc++.h>
 2 using namespace std; 
 3 #define LL long long
 4 #define lc (x<<1)  
 5 #define rc (x<<1|1)  
 6 #define mid (l+r)/2     
 7 int const N=200000+10;  
 8 char s[N];  
 9 LL f[N],v[N<<2];  
10 int n,k,sum[N<<2],pos[N<<2];   
11 void build(int x,int l,int r){
12     if(l==r){
13         sum[x]=s[l]=='1';  
14         if(sum[x]) pos[x]=l;  
15         return ;  
16     }
17     build(lc,l,mid);  
18     build(rc,mid+1,r);  
19     sum[x]=sum[lc]+sum[rc];  
20     if(pos[lc]) pos[x]=pos[lc];  
21     else pos[x]=pos[rc];  
22 }
23 int query(int x,int l,int r,int ll,int rr){
24     if(ll<=l && r<=rr){
25         return pos[x] ; 
26     }
27     int t1=0,t2=0;  
28     if(ll<=mid)  t1=query(lc,l,mid,ll,rr);  
29     if(t1) return t1;  
30     if(rr>mid)   t2=query(rc,mid+1,r,ll,rr);  
31     return t2;  
32 }
33 void insert(int x,int l,int r,int p,LL tv){
34     if(l==r){
35         v[x]=tv;  
36         return;  
37     }
38     if(p<=mid) insert(lc,l,mid,p,tv);  
39     else insert(rc,mid+1,r,p,tv);  
40     v[x]=min(v[lc],v[rc]);  
41 }
42 LL ask(int x,int l,int r,int ll,int rr){  
43     if(ll>rr) return 1e18;     
44     if(ll<=l && r<=rr) {
45         return v[x];  
46     }
47     LL res=1e18;  
48     if(ll<=mid)  res=min(res,ask(lc,l,mid,ll,rr));  
49     if(rr>mid)   res=min(res,ask(rc,mid+1,r,ll,rr));  
50     return res;  
51 }
52 int main(){
53     scanf("%d%d",&n,&k);  
54     scanf("%s",s+1); 
55     build(1,1,n);   
56     for(int i=1;i<=n;i++){
57         f[i]=f[i-1]+i;  
58         int t=query(1,1,n,max(1,i-k),i);  
59         if(t) {
60             int p=max(1,t-k-1);  
61             LL tmp=ask(1,1,n,p,i-1);  
62             if(t-k-1<1) tmp=0;  
63             f[i]=min(f[i],tmp+t);   
64         }
65         insert(1,1,n,i,f[i]);  
66     }  
67     cout<<f[n]<<endl;  
68     return 0;  
69 }
View Code

 

转载于:https://www.cnblogs.com/ZJXXCN/p/11601223.html


http://www.ppmy.cn/news/167105.html

相关文章

hdu 1216

主题思想&#xff1a; 简单模拟&#xff0c;打表 先执行一遍&#xff0c;算出第3000个数的大小&#xff0c;然后&#xff0c;以第3000个数&#xff0c;为上限&#xff0c;申请数组空间&#xff0c;和执行初始化&#xff0c;最后AC #include <iostream> #include<cst…

洛谷P1216数字三角形 ——动态规划

题目描述 观察下面的数字金字塔。 写一个程序来查找从最高点到底部任意处结束的路径&#xff0c;使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 在上面的样例中,从 7→3→8→7→5 的路径产生…

css定位 1216

定位的分类 static relative absolute fixedstatic 标准的 默认的 默认的定位&#xff0c;没有偏移效果 除了它外的所有其它定位&#xff0c;都会具有偏移的能力 relative 相对定位 特点&#xff1a; 偏移参考&#xff0c;以自身为参考 原来的位置&#xff0c;占据文档流…

Lightoj 1216

题目链接&#xff1a;点这里 题意&#xff1a;求水杯中水的体积。 思路&#xff1a;推公式。 我猜的ABC和ADE相似&#xff08;但是不知道证明&#xff09;&#xff0c;可以求出水的另一底面半径。 &#xff08;路过大牛知道怎么证明或者知道我的是错的一定给提出来啊。&…

洛谷P1216 2022.5.22 13:29

C&#xff1a;&#xff08;100分&#xff09; 我理解的大概原理&#xff1a; 题目&#xff1a;“从最高点到底部任意处结束的路径&#xff0c;使路径经过数字的和最大” 也就是找下面其中的一条路线&#xff0c;然后把这条路线上的所有数加起来&#xff0c;找到和数最大的那…

hpm1216nfh驱动程序_惠普M1216nfh驱动下载

惠普M1216nfh打印机是一款集打印、复印、扫描、传真为一体的多功能商用打印机&#xff0c;支持有线网络打印&#xff0c;分辨率高&#xff0c;可以满足很多大型企业的需求。今天小编带来了此款打印机的驱动程序&#xff0c;安装之后就可以实现打印机的正常工作了&#xff0c;欢…

java打jar包并包装成exe解压即用

1首先找到要加载的main方法类 public static void main(String[] args) { //创建该对象则调用构造方法&#xff0c;对象实现ActionListener则自动调用actionPerformed&#xff08;&#xff09;方法new PicdealMain();}2.点击 idea&#xff1a;File->Project Struce…(快捷键…

QC协议+华为FCP+三星AFC快充取电5V9V芯片FS2601应用

1、概述 FS2601是一款符合USB QC2.0、QC3.0、华为FCP和三星AFC快充协议的受电端&#xff08;诱骗取电&#xff09;协议芯片&#xff0c;让适配器输出合适的电压给产品供电&#xff0c;可广泛应用于各个领域的各种产品&#xff0c;如无线充电、小家电、老化器、智能机器人等。 …