隐藏页面特效

[选择客栈]

P1311

1|0[选择客栈]


1|1题目大意:选择同色调的不同客栈且满足之间至少存在一间客栈的最低消费≤p的方案数


1|2做法:(层层递进嘛)


1:60分的做法:直接暴力枚举i,j两个客栈判断是不是相同色调的不同客栈,然后从i枚举到j寻找是不是其中一间客栈的最低消费小于pans++,break

#include <cstdio> #include <iostream> #include <algorithm> using namespace std; const int maxn = 200005; int n,k,p,ans; int cnt[55],val[maxn],color[maxn]; int main() { scanf("%d%d%d",&n,&k,&p); for(int i=1;i<=n;i++) scanf("%d%d",&color[i],&val[i]); for(int i=1;i<n;i++) for(int j=i+1;j<=n;j++) { if(color[i] != color[j]) continue; for(int l=i;l<=j;l++) { if(val[l] <= p) { ans ++; break; } } } printf("%d\n",ans); return 0; }

但是我发现从i枚举到j判断是不是有一间客栈的最低消费是不是小于等于p,可以用前缀和来优化,sum[i]表示前i间客栈中满足小于等于p的个数,那么ij的个数不就是sum[j]sum[i1]吗?只需要判断是不是大于等于1就可以了

#include <cstdio> #include <iostream> #include <algorithm> using namespace std; const int maxn = 200005; int n,k,p,ans; int cnt[55],val[maxn],color[maxn]; int sum[maxn]; int main() { scanf("%d%d%d",&n,&k,&p); for(int i=1;i<=n;i++) { scanf("%d%d",&color[i],&val[i]); if(val[i] <= p) sum[i] = sum[i-1] + 1; else sum[i] = sum[i-1]; } for(int i=1;i<n;i++) for(int j=i+1;j<=n;j++) { if(color[i] != color[j]) continue; if(sum[j] - sum[i-1] >= 1) ans ++; } printf("%d\n",ans); return 0; }

但是你会发现还是60。。。

2:80分的做法:优化了60分的暴力:因为判断两个客栈是不是同色调的太浪费时间了,那么我们可以用一个pos数组把相同颜色的位置全都记录下来,这样就大大减少了枚举量,然后就会喜提80

#include <cstdio> #include <iostream> #include <algorithm> using namespace std; const int maxn = 200005; int n,k,p,ans; int cnt[55],val[maxn],color[maxn]; int sum[maxn],pos[55][maxn]; int main() { scanf("%d%d%d",&n,&k,&p); for(int i=1;i<=n;i++) { scanf("%d%d",&color[i],&val[i]); cnt[color[i]] ++; pos[color[i]][cnt[color[i]]] = i; if(val[i] <= p) sum[i] = sum[i-1] + 1; else sum[i] = sum[i-1]; } for(int col=0;col<k;col++) for(int i=1;i<cnt[col];i++) for(int j=i+1;j<=cnt[col];j++) { if(sum[pos[col][j]] - sum[pos[col][i]-1] >= 1) ans ++; } printf("%d\n",ans); return 0; }

3:100分做法:优化了80分的做法,考虑枚举两个客栈i,j的时候,如果i客栈与j客栈之间有满足最低消费小于等于p的客栈L的话,那么j后面相同颜色的客栈c,一定可以与i客栈匹配,因为越往后位置越靠后,那么[i,c]就都会包含这个满足最低消费p的客栈L,所以ans不用一个一个加,而是可以把j客栈之后的所有客栈都加进去。

#include <cstdio> #include <iostream> #include <algorithm> using namespace std; const int maxn = 200005; int n,k,p,ans; int cnt[55],val[maxn],color[maxn]; int sum[maxn],pos[55][maxn]; int main() { scanf("%d%d%d",&n,&k,&p); for(int i=1;i<=n;i++) { scanf("%d%d",&color[i],&val[i]); cnt[color[i]] ++; pos[color[i]][cnt[color[i]]] = i; if(val[i] <= p) sum[i] = sum[i-1] + 1; else sum[i] = sum[i-1]; } for(int col=0;col<k;col++) for(int i=1;i<cnt[col];i++) for(int j=i+1;j<=cnt[col];j++) { if(sum[pos[col][j]] - sum[pos[col][i]-1] >= 1) { ans += cnt[col] - j + 1; break; } } printf("%d\n",ans); return 0; }

__EOF__

本文作者风丨铃
本文链接https://www.cnblogs.com/-Wind-/p/11854790.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   风丨铃  阅读(315)  评论(4编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示