• CF56E 【Domino Principle】


    CF56E 【Domino Principle】
    $ $

    题目翻译:

    (n) ( (n le 10^5) ) 个多米诺骨牌在一条直线上,给定他们的坐标 (x)和高度 (h) ( (x) 越大则越靠右) ,求出当第 (i) 个骨牌向右倒下时会有几个骨牌倒下。第 (i) 块骨牌能压倒的范围在 ([x_i+1,x_i+h_i-1]) 之间。

    需要注意的地方:

    • 输入中骨牌的 (x) 值不一定有序
    • 被压倒骨牌可能也会压倒其他骨牌

    思路:

    直接暴力算肯定会T,二分的话因为会有重复部分所以也不好做,因此考虑动态规划。

    1. 先按照 (x) 坐标排正序,但枚举时要从后向前枚举 (因为后面骨牌的不会影响前面,因此先从后面算
    2. 每次计算 (ans_i) 时先考虑 (i) 能否压倒 (i+1),如果可以就加上 (ans_{i+1}) ,然后再看 (i) 能否压倒 (i+1) 不能压倒的第一块骨牌,可以答案就再加上那块骨牌的答案,以此类推。

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<bitset>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    
    using namespace std;
    
    int read()
    {
    	int ans=0,f=1;
    	char c=getchar();
    	while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
    	while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
    	return ans*f;
    }
    
    const int N=1e5+5;
    int n,ans[N],last[N];
    // last 存储排序后的第 i 块骨牌压不倒的第一块骨牌的位置
    
    struct Node
    {
    	int x,h,p;  // p 用来标记问题编号
    	bool operator < (const Node &t)const
    	{  // 重载运算符,排序时按照 x 正序排列
    		return t.x>x;
    	}
    }a[N];
    
    int main()
    {
    	n=read();
    	for(int i=1;i<=n;++i)
    	{
    		a[i].x=read();
    		a[i].h=read();
    		a[i].p=i;
    	}  // 读入
    	sort(a+1,a+1+n); / / 排序
    	for(int i=1;i<=n;++i)
    		ans[i]=1; // 因为压倒一块骨牌时它自己一定会倒(这不是废话吗...),所以答案至少是 1
    	for(int i=n-1;i>=1;--i)
        // 因为最后面的骨牌谁都压不到,所以直接从 n-1 开始算
    	{
    		int now=i+1;  // now 存储下一次需要比较的骨牌下标,最开始为 i+1
    		while(now&&a[i].x+a[i].h>a[now].x)
            // 如果后面还有骨牌 并且 这块骨牌能压倒下一个需要压倒骨牌
    		{
    			ans[a[i].p]+=ans[a[now].p];
                // 就把答案加上下一块需要压倒的骨牌的答案
    			now=last[now];
                // 并更新 now 为 刚压倒的这块骨牌 的首个无法压倒的骨牌的下标
    		}
    		last[i]=now;  // 维护 last ,因为下标为 now 的骨牌已经无法被压倒,且它前面的骨牌都可以被压倒,所以 now 就是这块骨牌的首个无法被压倒的骨牌
    	}
    	for(int i=1;i<=n;++i)
        //输出时注意按照原输入顺序来输出
    		printf("%d ",ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    python --异常处理
    Python -- 函数对象
    python --循环对象
    python --循环设计
    python --模块
    python --文本文件的输入输出
    xpee.vbs
    oracle 有个xe版本
    POI对Excel单元格进行颜色设置
    POI进行ExcelSheet的拷贝
  • 原文地址:https://www.cnblogs.com/blackbird137/p/13550357.html
Copyright © 2020-2023  润新知