题干:

题目大意:

题意是在一条直线上坐落着不同位置的灯塔,每一个灯塔有自己的power level,当作是射程范围。现在从最右边的灯塔开始激发,如果左边的灯塔在这个灯塔的范围之内,那么将会被毁灭。否则会被激发,留下自己。

解题报告:

dp求解:

现在可以从右边放置一个灯塔,位置和power level都可以自己定义。问各种情况中最小的灯塔被毁灭的数量。

dp[x]表示到x个灯塔的时候毁灭的最小数量。对于第x个灯塔来说,求出不再自己范围内的上一个的灯塔位置i,因此在自己范围内的灯塔数量也能够得知x-i+1。

那么会有dp[x]=dp[i]+x-i+1。这个是在第x炸弹被激发的情况下,毁灭的灯塔数量。

而今,因为可以在右边放置一个灯塔了。所以就求出dp[i]+(n-i) (1<=i<=n)的最小值。

AC代码1:(标解dp)

AC代码2:(二分)

#include<bits/stdc++.h>using namespace std;
pair<int,int> pr[100000 + 5];
int dp[100000 + 5];
int main() {int n;cin>>n;for(int i = 1; i<=n; i++) {scanf("%d%d",&pr[i].first,&pr[i].second);}sort(pr+1,pr+n+1);dp[0]=0;
//  pr[n+1].first=-1;for(int i = 1; i<=n; i++) {int loc = lower_bound(pr+1,pr+i+1,make_pair(pr[i].first - pr[i].second,-1)) - pr;if(loc)dp[i] = dp[loc - 1] + (i-loc);else dp[i] = i-1;
//      printf("%d = %d\n",i,dp[i]);}int minn = 0x3f3f3f3f;for(int i = 1; i<=n; i++) {minn = min(minn,dp[i] + (n-i) );}printf("%d\n",minn);return 0 ;
}

AC代码3:(网络版的二分,跟第二个差不多)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define INF 0x3fffffffconst int maxn = 100005;int n;
int dp[maxn];//记录毁灭的最小值
struct no {int a;int b;
} node[maxn];
bool cmp(const no &n1, const no &n2) {return n1.a < n2.a;
}
void solve() {int i;sort(node + 1, node + n + 1, cmp);for (i = 1; i <= n; i++) {no nx;nx.a = node[i].a - node[i].b;int pos = lower_bound(node + 1, node + n + 1, nx, cmp) - node;if (pos)dp[i] = dp[pos - 1] + (i - pos);//因为最靠右的会被激发,致使范围之内的会被毁灭elsedp[i] = i - 1;//除了自己全部毁灭
//      printf("%d = %d\n",i,dp[i]);}int res = n;for (i = 1; i <= n; i++) {res = min(res, dp[i] + (n - i));}printf("%d", res);
}int main() {scanf("%d",&n);for (int i = 1; i <= n; i++) {scanf("%d%d", &node[i].a, &node[i].b);}solve();return 0;
}

依旧二分AC4:

#include<bits/stdc++.h>using namespace std;
const int MAX = 1e5 + 5;
int dp[MAX];
pair<int,int> pr[MAX];
int main()
{int n;cin>>n;for(int i = 1; i<=n; i++) {scanf("%d%d",&pr[i].first,&pr[i].second);}sort(pr+1,pr+n+1);dp[1]=1;//记录存活个数
//  dp[0]=0;for(int i = 2; i<=n; i++) {if(pr[i].first - pr[i].second <=0) {dp[i]=1;continue;}int pos = lower_bound(pr+1,pr+i+1,make_pair(pr[i].first - pr[i].second,-1)) - pr;//会被辐射到的 pos--;//第一个不会被辐射到的dp[i] = dp[pos]+1;}int minn = 0x3f3f3f3f;for(int i = 1; i<=n; i++) {//minn = min(minn,n - i + (i-dp[i]));minn = min(minn,n-dp[i]);}printf("%d\n",minn);return 0 ;} 

依旧二分AC5:

#include<bits/stdc++.h>using namespace std;
const int MAX = 1e5 + 5;
int dp[MAX];
pair<int,int> pr[MAX];
int main()
{int n;cin>>n;for(int i = 1; i<=n; i++) {scanf("%d%d",&pr[i].first,&pr[i].second);}sort(pr+1,pr+n+1);
//  dp[1]=1;//记录存活个数 dp[0]=0;for(int i = 1; i<=n; i++) {//这里是从1开始了、、、
//      if(pr[i].first - pr[i].second <=0) {dp[i]=1;continue;}int pos = lower_bound(pr+1,pr+i+1,make_pair(pr[i].first - pr[i].second,-1)) - pr;//会被辐射到的 pos--;//第一个不会被辐射到的dp[i] = dp[pos]+1;}int minn = 0x3f3f3f3f;for(int i = 1; i<=n; i++) {//minn = min(minn,n - i + (i-dp[i]));minn = min(minn,n-dp[i]);}printf("%d\n",minn);return 0 ;} 

ps:其实上面几个代码都可以lowerbound(pr+1 , pr+i , ....) - pr 就行了,不需要pr+i+1.。。但是其实好像是一模一样的。(本以为可以不用判断pos的结果等于pre的情况(也就是一个都没找到   的情况),但是发现这样写也是要考虑的,因为你pr+i的话,lowerbound没找到也是要返回pos==pre这个的啊,结合那个【CodeForces - 799C】Fountains去理解下、、)

二分网络版AC代码6:(其实跟AC代码4是一样的)

//meek///#include<bits/stdc++.h>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include<iostream>
#include<bitset>
using namespace std ;
#define mem(a) memset(a,0,sizeof(a))
#define pb push_back
#define fi first
#define se second
#define MP make_pair
typedef long long ll;const int N = 201000;
const int M = 1000001;
const int inf = 0x3f3f3f3f;
const int MOD = 100003;
const double eps = 0.000001;struct ss{int p,s,S;
}a[N];
int n,b[N],H[N],t[M],sum[N],dp[M+5];
int cmp(ss s1,ss s2) {return s1.p<s2.p;}int main () {scanf("%d",&n);for(int i=1;i<=n;i++) {scanf("%d%d",&a[i].p,&a[i].s);a[i].S=a[i].p-a[i].s-1;}int cnt=0;   int tmp;sort(a+1,a+n+1,cmp);int ans=0,L=0;int cc=1;for(int i=0;i<=M;i++) {if(i==a[cc].p) {if(a[cc].S>=0) {dp[i] = dp[a[cc].S] +1;}else dp[i] = 1;cc++;}else dp[i] = dp[i-1];ans=max(dp[i],ans);// cout<<dp[i]<<endl;}cout<<n-ans<<endl;return 0;
}daima

标解dp代码7:(wlb)

#pragma warning(disable:4996)
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll;
#define INF 0x3fffffffconst int maxn = 1000005;int n, nmax;
int dp[maxn];
int d[maxn];//记录能够存活的最大值void input() {int i, a;scanf("%d", &n);nmax = 0;for (i = 1; i <= n; i++) {scanf("%d", &a);//记录炸弹位置scanf("%d", &d[a]);//记录该位置炸弹的范围nmax = max(a, nmax);}
}void solve() {int i;if (d[0])dp[0] = 1;int res = n;res = min(res, n - dp[0]);for (i = 1; i <= nmax; i++) {if (d[i] == 0) {dp[i] = dp[i - 1];//如果该位置没有炸弹} else {if (d[i] >= i) {dp[i] = 1;//这个位置只剩下一个了} else {dp[i] = dp[i - d[i] - 1] + 1;//表示在该炸弹的范围内只存活了自己,所以在之前的位置加1}}res = min(res, n - dp[i]);}printf("%d", res);
}int main() {//freopen("i.txt", "r", stdin);//freopen("o.txt", "w", stdout);input();solve();//system("pause");return 0;
}

超时代码:

#include<bits/stdc++.h>using namespace std;
int pos[100000 + 5],b[100000 +5];
int main()
{int n;scanf("%d",&n);for(int i = 1; i<=n; i++) {scanf("%d %d",&pos[i],&b[i]);}int loc,ans,minn = 0x3f3f3f3f;for(int i = n; i>=1; i--) {loc = i;ans = 0;while(loc > 1) {int pre = loc;if(pos[loc] - pos[loc-1] > b[loc]) {loc--;continue;}loc = lower_bound(pos+1,pos+loc+1,pos[loc] - b[loc]) - pos;if(loc == pre) continue;ans += (pre - loc );loc--;}minn = min(minn,ans + (n-i));
//      printf("mi = %d\n",minn);}printf("%d\n",minn);return 0 ;
}
//4
//1 9
//3 1
//6 1
//7 4

【CodeForces - 608C】Chain Reaction (二分 或 dp ,思维)相关推荐

  1. Codeforces - 706B - Interesting drink - 二分 - 简单dp

    https://codeforces.com/problemset/problem/706/B 因为没有看见 $x_i$ 的上限是 $10^5$ ,就用了二分去做,实际上这道题因为可乐的价格上限是 $ ...

  2. 【题解】hdu 3586 Information Disturbing 二分 树形dp

    题目描述 Information Disturbing Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Jav ...

  3. 洛谷 P1800 software_NOI导刊2010提高(06)(二分答案+DP检验)

    P1800 software_NOI导刊2010提高(06) 标签 二分答案 难度 普及/提高- 题目描述 一个软件开发公司同时要开发两个软件,并且要同时交付给用户,现在公司为了尽快完成这一任务,将每 ...

  4. 吉吉王国(二分+树形dp)

    吉吉王国 题意: n个点,m个边,有边权,现在要求叶子节点无法与1号点连通,要求切断的总长度不能超过m,且切断的最长的长度尽可能断 题解: 题意的前半部分可以确定是树形dp,后半部分可以确定为是二分 ...

  5. Codeforces 148D. Bag of mice(概率dp)

    Codeforces 148D. Bag of mice(概率dp) Description The dragon and the princess are arguing about what to ...

  6. 校内互测 B. 王者荣耀 (二分答案+dp)

    B. 王者荣耀 时间限制:1s 内存限制:128MB 问题描述 从未来回来后,他知道他最近要打 n 局王者荣耀,其中第 i 局需要耗时li,并且这个顺序在时间上是不可改变的.作为一个很(mei)有自制 ...

  7. CSP-S 2019————Emiya 家今天的饭————DP+思维

    题解:本题主要考查DP+思维. 简要题意:一个矩阵,要求每行只选一个节点,每列选的节点不能超过所有选的节点的一半,不能不选,给出每个节点的选择方案数,求总方案数. 1.DP+思维: (1).维护每列已 ...

  8. Ivan the Fool and the Probability Theory-Codeforces Round #594 (Div. 2)-C题(dp+思维)

    Ivan the Fool and the Probability Theory-Codeforces Round #594 (Div. 2)-C题(dp+思维) time limit per tes ...

  9. CodeForces - 1560F2 Nearest Beautiful Number (hard version)(二分+数位dp)

    题目链接:点击查看 题目大意:给出一个十进制数字 nnn 和一个约束 kkk,问大于等于 nnn 且满足不同的数位个数小于等于 kkk 的最小的数字是多少 题目分析:自己写的贪心太丑了,就不放上来丢人 ...

最新文章

  1. 一文告诉你Adam、AdamW、Amsgrad区别和联系 重点
  2. 吴恩达的机器学习--矩阵运算
  3. altium pcb 信号高亮_Altium Designer PCB的时候 高亮显示引脚连线
  4. GitHub:GitHub简介、使用方法、经验总结(图文教程)之详细攻略(持续更新!)
  5. HTML第十章作业代码,HTML教程10第十章.doc
  6. .NET 开源配置组件 AgileConfig 初体验
  7. learning linux
  8. python 网格搜索_Python机器学习:6.4 通过网格搜索调参
  9. win10应用商店怎么重新安装?
  10. PMP课程笔记:第1-3章 引论 项目运行环境 项目经理
  11. 雨笋教育干货分享:0day漏洞利用及抓取的姿势
  12. 智能客服、聊天机器人的应用和架构、算法分享和介绍
  13. taptap评论爬虫
  14. CSAPP第四章家庭作业参考答案
  15. Java基础关于接口的案例及多态的引用类型转换练习题
  16. torch.cat() 和 torch.stack()
  17. NISP证书换取CISP证书需要哪些条件?
  18. “武汉城市之根”发声: 又见宝藏系列数字藏品独家发行
  19. 计算机视觉摔倒检测,有关摔倒检测数据集(fall detection databases)
  20. UVa 1025 (DAG 上的动态规划,有固定终点的最短时间,逆推法)

热门文章

  1. [Bugku][Crypto][CTF][2020]Crypto 1-20 write up
  2. java嵌入式开发neo4j_java-嵌入式Neo4j实际如何工作?
  3. 上传本地项目到gitee_用git上传本地文件到码云gitee的方法
  4. antd 日期时间选择_Excel最全时间类函数总结,有必要收藏一下哦
  5. python随机划分数据集_Python之机器学习-sklearn生成随机数据
  6. 重燃你的PHP安全之火.pdf,读《重燃你的php之火》总结笔记
  7. 【Modern OpenGL】第一个三角形
  8. Linux编程练习 --多线程5--信号量(semaphore)
  9. sql字符串拼接_Mybatis的SqlSession执行sql过程
  10. python应声虫程序_Python编程基础