【CodeForces 990E】Post Lamps

传送门戳这里

Luogu & CodeForces

题目描述

Adilbek‘s house is located on a street which can be represented as the OX axis. This street is really dark, so Adilbek wants to install some post lamps to illuminate it. Street has nn positions to install lamps, they correspond to the integer numbers from 00 to n - 1n−1 on the OX axis. However, some positions are blocked and no post lamp can be placed there.

There are post lamps of different types which differ only by their power. When placed in position xx , post lamp of power ll illuminates the segment [x; x + l][x;x+l] . The power of each post lamp is always a positive integer number.

The post lamp shop provides an infinite amount of lamps of each type from power 11 to power kk . Though each customer is only allowed to order post lamps of exactly one type. Post lamps of power ll cost a_lal? each.

What is the minimal total cost of the post lamps of exactly one type Adilbek can buy to illuminate the entire segment [0; n][0;n] of the street? If some lamps illuminate any other segment of the street, Adilbek does not care, so, for example, he may place a lamp of power 33 in position n - 1n−1 (even though its illumination zone doesn‘t completely belong to segment [0; n][0;n] ).

解题思路

既然数据不大,我们可以想想怎么暴力。

显然暴利的方法就是贪心,从头到尾一个一个放,遇到障碍再向前倒退,当照明距离越短时复杂度越小,应该是调和级数,差不多nlogn。

还有一点找障碍前面的能放的位置的时候千万不能循环着找,会T。

那么我们先O(n)的时间内预处理出来一个数组,表示当前位置之前包括当前位置的第一个能放路灯的地方的位置,每次查询这个数组就好了。

代码

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int n,m,k;
 7 bool ba[1000010];
 8 int p[1000010],l[1000010];
 9 inline void read(register int &x){
10     x=0; register char ch=getchar();
11     while(ch<‘0‘||ch>‘9‘)ch=getchar();
12     while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘,ch=getchar();
13 }
14 inline long long calc(int num){
15     int pos=0;
16     register long long ans=p[num];
17     if(ba[0])return -1;
18     while(pos<n){
19         register int nepos=pos+num;
20         if(nepos>=n)return ans;
21         if(ba[nepos]){
22             if(l[nepos]==pos)return -1;
23             else nepos=l[nepos];
24         }
25         pos=nepos;
26         ans+=(long long)p[num];
27     }
28     return ans;
29 }
30 int main(){
31     read(n),read(m),read(k);
32     for(register int i=1;i<=m;i++){
33         register int pos;
34         read(pos);
35         ba[pos]=1;
36     }
37     for(register int i=1;i<=k;i++)read(p[i]);
38     for(register int i=1;i<=n;i++){
39         if(ba[i])l[i]=l[i-1];
40         else l[i]=i;
41     }
42     long long ans=9999999999999LL;
43     for(register int i=1;i<=k;i++){
44         long long tmp=calc(i);
45         if(tmp!=-1)ans=min(ans,tmp);
46     }
47     if(ans==9999999999999)cout<<-1<<endl;
48     else cout<<ans<<endl;
49 }

原文地址:https://www.cnblogs.com/Fang-Hao/p/9255639.html

时间: 2024-08-06 14:20:43

【CodeForces 990E】Post Lamps的相关文章

【codeforces 718E】E. Matvey&#39;s Birthday

题目大意&链接: http://codeforces.com/problemset/problem/718/E 给一个长为n(n<=100 000)的只包含‘a’~‘h’8个字符的字符串s.两个位置i,j(i!=j)存在一条边,当且仅当|i-j|==1或s[i]==s[j].求这个无向图的直径,以及直径数量. 题解:  命题1:任意位置之间距离不会大于15. 证明:对于任意两个位置i,j之间,其所经过每种字符不会超过2个(因为相同字符会连边),所以i,j经过节点至多为16,也就意味着边数至多

【codeforces 415D】Mashmokh and ACM(普通dp)

[codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=2000),问满足[数列长度是k && 数列中每一个元素arr[i]在1~n之间 && 数列中元素可以重复]的数列有多少个?结果对10^9+7取余 解题思路:dp[i][j]表示长度是j,最后一位是i的种数 if(kk%i==0) dp[kk][j+1]+=dp[i][j] 1 #i

【Codeforces 368A】Brain&#39;s Photos 水题

黑白灰都是#Black&White #include <cstdio> int n,m; int main() { scanf("%d%d",&n,&m); int ok=0; for(int i=0;i<n;i++) for(int j=0;j<m;j++) { char s[5]; scanf("%s",s); if(s[0]!='W'&&s[0]!='B'&&s[0]!='G')

【Codeforces 1114C】Trailing Loves (or L&#39;oeufs?)

[链接] 我是链接,点我呀:) [题意] 问你n!的b进制下末尾的0的个数 [题解] 证明:https://blog.csdn.net/qq_40679299/article/details/81167283 这题的话m比较大, 做个质因数分解就ok>_< 算n!有多少个x因子的话 以5为例子 (n=25) 25 20 15 10 5 把他们都除5 5 4 3 2 1 然后再除5 1 所以总共有6个 转换成代码就是 while(n>0){ ans+=n/5; n = n/5; } [代码

【Codeforces 332C】Students&#39; Revenge

Codeforces 332 C 我爱对拍,对拍使我快乐... 题意:有\(n\)个议题,学生们会让议会同意\(p\)个,其中主席会执行\(k\)个, 每一个议题执行后主席会掉\(a_i\)的头发,不执行后议会会增加\(b_i\)的不开心值, 然后主席想让议会的不开心值最小,如果有多重方案就选自己头发掉的最少的: 而学生们想让主席的头发掉的最多,如果有多种方案让议会的不开心值最大. 问让议会同意哪\(p\)个会达到最好的效果. 思路1: 这是我的不对的思路. (虽然没提交 我们首先将所有的数按照

【Codeforces 429D】 Tricky Function

[题目链接] http://codeforces.com/problemset/problem/429/D [算法] 令Si = A1 + A2 + ... + Ai(A的前缀和) 则g(i,j) = Sj - Si f(i,j) = (i-j)^2 + (Si - Sj)^2 观察这个式子,我们发现可以用类似于平面最近点对的算法来求解该问题 [代码] #include<bits/stdc++.h> using namespace std; #define MAXN 100010 const

【Codeforces 105D】 Bag of mice

[题目链接] http://codeforces.com/contest/148/problem/D [算法] 概率DP f[w][b]表示还剩w只白老鼠,b只黑老鼠,公主胜利的概率,那么 : 1. 公主抓到白老鼠,概率为w/(w+b) 2. 公主抓到黑老鼠,那么龙也抓到黑老鼠,如果跑出来的老鼠是白颜色的,则概率为 : b / (w + b) * b / (w + b - 1) * w / (w + b - 2) * f[w-1][b-2] 否则,概率为 : b / (w + b) * (b -

【Codeforces 258A】 Game With Sticks

[题目链接] http://codeforces.com/contest/451/problem/A [算法] 若n和m中的最小值是奇数,则先手胜,否则后手胜 [代码] #include<bits/stdc++.h> using namespace std; int n,m; int main() { scanf("%d%d",&n,&m); if (min(n,m) % 2 == 0) printf("Malvika\n"); else

【Codeforces 258B】 Sort the Array

[题目链接] http://codeforces.com/contest/451/problem/B [算法] 模拟 在序列中找到一段单调递增的子序列,将这段序列反转,然后判断序列是否变得单调递增,即可 [代码] #include<bits/stdc++.h> using namespace std; const int MAXN = 1e5 + 10; int i,n,l,r; bool flag; int a[MAXN]; int main() { scanf("%d"