P1311 选择客栈[模拟]

题目描述

丽江河边有nn家很有特色的客栈,客栈按照其位置顺序从 11到nn编号。每家客栈都按照某一种色调进行装饰(总共 kk 种,用整数 00 ~k-1k?1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均有各自的最低消费。

两位游客一起去丽江旅游,他们喜欢相同的色调,又想尝试两个不同的客栈,因此决定分别住在色调相同的两家客栈中。晚上,他们打算选择一家咖啡店喝咖啡,要求咖啡店位于两人住的两家客栈之间(包括他们住的客栈),且咖啡店的最低消费不超过 pp

他们想知道总共有多少种选择住宿的方案,保证晚上可以找到一家最低消费不超过pp元的咖啡店小聚。

解析

看到题解有人RMQ了,也看到巨佬的ST表了,没错,我也是差不多的思路。但是我的想法似乎结合了题解区好几篇题解(雾。

首先我们先不考虑最低消费这个影响因素。对于每一个客栈\(i\),假设它的色调为\(k_i\),显然它可以与其左边的所有的与它色调相同的客栈构成合法解,因此它对答案造成的贡献就是在它左边的与它色调一致的客栈总个数。

接下来我们考虑加入最低消费这个因素。在加入这个因素后,对于客栈\(i\),它会与左边的某些符合要求的客栈构成合法解。根据题目,这个要求是咖啡店位于两人住的两家客栈之间(包括他们住的客栈),且咖啡店的最低消费不超过 p。所以我们只要知道对于客栈\(i\),它到它前面的某个客栈之间最低消费的最小值,就可以知道该情况是否构成合法解。而题目并没有区间修改这种操作,为了解决RMQ,我们不妨选择效率较高的ST表。

又,对于客栈\(i\),假设它左边有一个客栈\(j\)与其构成合法解,那么客栈\(j\)左边的所有客栈也一定与\(i\)构成合法解。

复杂度可能\(O(nk)\)吧,烂的很。

参考代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<vector>
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define N 200010
#define MOD 2520
#define E 1e-12
using namespace std;
inline int read()
{
    int f=1,x=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int sum[51][N],f[N][20],n,k,p;
int pre[N],last[51];
struct node{
    int rk,v;
}a[N];
inline int fmax(int x,int y){return x>y?x:y;}
inline int fmin(int x,int y){return x<y?x:y;}
inline void prework()
{
    int t=log(n)/log(2)+1;
    for(int j=1;j<t;++j)
        for(int i=1;i<=n-(1<<j)+1;++i)
            f[i][j]=fmin(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}
inline int query(int l,int r)
{
    int t=log(r-l+1)/log(2);
    return fmin(f[l][t],f[r-(1<<t)+1][t]);
}
int main()
{
    n=read(),k=read(),p=read();
    for(int i=1;i<=n;++i){
        a[i].rk=read(),f[i][0]=a[i].v=read();
        pre[i]=last[a[i].rk],last[a[i].rk]=i;
        sum[a[i].rk][i]++;
        for(int j=0;j<=k;++j)
            sum[j][i]+=sum[j][i-1];
    }
    prework();
    int ans=0;
    for(int j,i=1;i<=n;++i){
        if(sum[a[i].rk][i]-sum[a[i].rk][i-1]){
            if(sum[a[i].rk][i]==1) continue;
            for(j=pre[i];j;j=pre[j])
                if(query(j,i)<=p)break;
            ans+=sum[a[i].rk][j];
        }
    }
    printf("%d\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/DarkValkyrie/p/11602549.html

时间: 2025-01-17 20:47:29

P1311 选择客栈[模拟]的相关文章

P1311 选择客栈

题目描述 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均有各自的最低消费. 两位游客一起去丽江旅游,他们喜欢相同的色调,又想尝试两个不同的客栈,因此决定分别住在色调相同的两家客栈中.晚上,他们打算选择一家咖啡店喝咖啡,要求咖啡店位于两人住的两家客栈之间(包括他们住的客栈),且咖啡店的最低消费不超过 p . 他们想知道总共有多少种选择住宿的方案,保证晚上可

洛谷 P1311 选择客栈 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problem/show?pid=1311 题目描述 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均有各自的最低消费. 两位游客一起去丽江旅游,他们喜欢相同的色调,又想尝试两个不同的客栈,因此决定分别住在色调相同的两家客栈中.晚上,

洛谷P1311 选择客栈

时间复杂度O(N*K) 开两个后缀和数组 a[ i ].color[ j ] 表示在i之后 (包括 i ) 有多少间 客栈是j 颜色的 以及 a[ i ].last 表示在i之后 (包括i ) 第一个小于等于 x 的 咖啡店的坐标 并且要特判一下 a[ i ].last == i 的情况 这是颜色相同的咖啡店数量要减一 1 #include <cstdio> 2 #define For(i,j,k) for(int i=j;i<=k;i++) 3 #define LL long long

Luogu P1311 选择客栈

暴力 我一开始做这道题先想到的就是暴力... 所以先说一下暴力的做法.首先在输入的时候讲花费小于P的位置标记下来,然后用两层循环枚举所有的两个客栈的组合方案.再用一层循环将两个客栈之间的位置扫一遍,如果有被标记过得位置证明这种方案是可行的.将其统计下来. 暴力的代码 #include <iostream> #include <cstring> #include <cstdio> #include <cstring> const int maxn = 2e5+

洛谷P1311 [NOIP2011提高组Day1T2] 选择客栈

P1311 选择客栈 题目描述 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均有各自的最低消费. 两位游客一起去丽江旅游,他们喜欢相同的色调,又想尝试两个不同的客栈,因此决定分别住在色调相同的两家客栈中.晚上,他们打算选择一家咖啡店喝咖啡,要求咖啡店位于两人住的两家客栈之间(包括他们住的客栈),且咖啡店的最低消费不超过 p . 他们想知道总共有多少种选择

Noip2011 提高组 选择客栈

P1311 选择客栈 直通 思路: ①看题,我们可以发现一个显然的性质,即当最左边的客栈向右移动时,最右边的客栈时单调向右的,并且右端点往右的客栈也符合要求.(因为只要左侧有一个满足的,右边的自然可以选) 不妨将每种颜色的宾馆分别放到 vector 中. 然后在每个 vector 中枚举左端点,维护一个单调指针来确定右端点 (vector中的下标). 我们接下来就要快速判断一段区间是否合法,我们开一个ok数组,表示从i点开始最近的满足条件的位置(不考虑颜色). 这样的话转移就是: ok[i]=i

noip2011 选择客栈

P1311 选择客栈 375通过 1K提交 题目提供者该用户不存在 标签递推2011NOIp提高组 难度普及+/提高 提交该题 讨论 题解 记录 题目描述 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均有各自的最低消费. 两位游客一起去丽江旅游,他们喜欢相同的色调,又想尝试两个不同的客栈,因此决定分别住在色调相同的两家客栈中.晚上,他们打算选择一家咖啡店

NOIP201106选择客栈

(本来像这种东西我都是写进程序注释里的,然而杨老师说不写就罚跑圈..所以只能写了QAQ) 第一次写博,感觉没毛线好写的,贴道水题好了QAQ(其实是因为看WXJ和LJX围着这题的测试数据讨论了半个多小时屁结论都没有) NOIP201106选择客栈 难度级别:A: 运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述    丽江河边有n家很有特色的客栈,客栈按照其位置顺序从1到n编号.每家客栈都按照某一种色调进行装饰(总共k种,用整数0到k-1表示)

NOIP2011选择客栈[递推]

题目描述 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均有各自的最低消费. 两位游客一起去丽江旅游,他们喜欢相同的色调,又想尝试两个不同的客栈,因此决定分别住在色调相同的两家客栈中.晚上,他们打算选择一家咖啡店喝咖啡,要求咖啡店位于两人住的两家客栈之间(包括他们住的客栈),且咖啡店的最低消费不超过 p . 他们想知道总共有多少种选择住宿的方案,保证晚上可