8.4考试总结(NOIP模拟30)[毛一琛·毛二琛·毛三琛]
最有名的莫过于想死一次吗。
前言
至今都不知道题目是个啥。。。
T1 毛一琛
解题思路
\(\mathcal{Meet\;In\;The\;Middle}\)
其实就是一个爆搜。。。
把整个区间分为两部分,每个部分有两个集合。
对于每一个数状态只有三种:集合1,集合2,不选。
然后对于已经两个区间内,如果每个区间中的两个集合价值之差相同的话,
这四个集合所组合成的两个集合一定可以分成两个值相同的集合。
然后就是对于了两半分别 DFS 就好了。。
- 注意:全部开 long long 或者 map套 vector会 TLE。
code
#include<bits/stdc++.h>
//#define int long long
using namespace std;
int n,ans,cnt,s[30];
bool vis[1<<21];
vector<int> v[1<<21];
unordered_map<int,int> mp;
void dfs(int opt,int x,int anc,int sum1,int sum2,int sta)
{
if(x==anc+1)
{
if(opt==1)
{
if(mp.find(abs(sum1-sum2))==mp.end()) return ;
int tmp=mp.find(abs(sum1-sum2))->second;
for(int i=0;i<v[tmp].size();i++)
vis[sta<<n/2|v[tmp][i]]=true;
}
else
{
if(mp.find(abs(sum1-sum2))==mp.end()) mp[abs(sum1-sum2)]=++cnt;
v[mp.find(abs(sum1-sum2))->second].push_back(sta);
}
return ;
}
dfs(opt,x+1,anc,sum1+((opt)?s[x+n/2]:s[x]),sum2,sta|(1<<x-1));
dfs(opt,x+1,anc,sum1,sum2+((opt)?s[x+n/2]:s[x]),sta|(1<<x-1));
dfs(opt,x+1,anc,sum1,sum2,sta);
}
signed main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&s[i]);
dfs(0,1,n/2,0,0,0);
dfs(1,1,n-n/2,0,0,0);
for(int i=1;i<(1<<n);i++) ans+=vis[i];
printf("%d",ans);
return 0;
}
T2 毛二琛
解题思路
非常好的一个题(至少对于我来说是这样的)
首先发现对于 swap 的顺序是有一定优先级的。。
然后我们循环求出每一个 swap 操作的优先级。
接下来 DP 定义 f[i][j] 为前 i 个 swap 操作中 第 i 个优先级排名为 j
就可以简单的写出 \(\mathcal{O(n^3)}\) 的 DP转移。
发现可以前缀和优化,然后就可以把复杂度降低到 \(\mathcal{O(n^2)}\)
可以通过此题。
- 注意:操作优先级以及 DP 的边界问题。
code
70pts
#include<bits/stdc++.h>
#define int long long
#define f() cout<<"Pass"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch>'9'||ch<'0')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
const int N=5e3+10,mod=1e9+7;
int n,ans,f[N][N],s[N],opt[N];
signed main()
{
n=read();
for(int i=1;i<=n;i++)
s[i]=read()+1;
for(int i=1;i<=n;i++)
{
if(s[i]-i>1)
{
if(!opt[i-2]) opt[i-2]=opt[i-3];
for(int j=i-1;j<=s[i]+1;j++)
opt[j]=opt[j-1]+1;
}
else
{
if(!opt[s[i]+1]) opt[s[i]+1]=opt[s[i]+2];
for(int j=i-2;j>=s[i];j--)
opt[j]=opt[j+1]+1;
}
}
f[1][1]=1;
for(int i=2;i<n;i++)
for(int j=1;j<i;j++)
{
if(opt[i]>opt[i-1])
for(int k=j+1;k<=i;k++)
f[i][k]=(f[i][k]+f[i-1][j])%mod;
if(opt[i]<opt[i-1])
for(int k=1;k<=j;k++)
f[i][k]=(f[i][k]+f[i-1][j])%mod;
if(opt[i]==opt[i-1])
for(int k=1;k<=i;k++)
f[i][k]=(f[i][k]+f[i-1][j])%mod;
}
for(int i=1;i<n;i++)
ans=(ans+f[n-1][i])%mod;
printf("%lld",ans);
return 0;
}
正解
#include<bits/stdc++.h>
#define int long long
#define f() cout<<"Pass"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch>'9'||ch<'0')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
const int N=5e3+10,mod=1e9+7;
int n,ans,f[N][N],pre[N],s[N],opt[N];
signed main()
{
n=read();
for(int i=1;i<=n;i++)
s[i]=read()+1;
for(int i=1;i<=n;i++)
if(s[i]-i>1)
{
if(!opt[i-2]&&i-3>=0) opt[i-2]=opt[i-3];
for(int j=i-1;j<=s[i]+1;j++)
opt[j]=opt[j-1]+1;
}
else
{
if(!opt[i-1]&&i-2>=0) opt[i-1]=opt[i-2];
for(int j=i-2;j>=s[i];j--)
opt[j]=opt[j+1]+1;
}
f[1][1]=pre[1]=1;
for(int i=2;i<n;i++)
{
if(opt[i]>opt[i-1])
for(int k=2;k<=i;k++)
f[i][k]=(f[i][k]+pre[k-1])%mod;
if(opt[i]<=opt[i-1])
for(int k=1;k<i;k++)
f[i][k]=(f[i][k]+pre[i-1]-pre[k-1]+mod)%mod;
for(int j=1;j<=i;j++)
pre[j]=(pre[j-1]+f[i][j])%mod;
}
for(int i=1;i<=n-1;i++)
ans=(ans+f[n-1][i])%mod;
printf("%lld",ans);
return 0;
}
T3 毛三琛
解题思路
其实正解的时间复杂度是假的。
二分答案,查找每一个 x 下最小的最大值。
然后就是一些剪枝。。(不要开long long)
然后就没了。。(又水了一篇题解)(逃
code
#include<bits/stdc++.h>
#define ull unsigned long long
#define f() cout<<"Pass"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch>'9'||ch<'0')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
const int N=1e4+10;
int n,m,ans=1e9,mod,sum,s[N],q[N];
bool check(int x)
{
int tot=1,res=0;
for(int i=1;i<=n;i++)
{
if(q[i]>x) return false;
if(res+q[i]<=x) res+=q[i];
else res=q[i],tot++;
if(tot>m) return false;
}
return tot<=m;
}
signed main()
{
n=read();
mod=read();
m=read();
for(int i=1;i<=n;i++)
s[i]=read();
for(int x=0;x<mod;x++)
{
sum=0;
for(int i=1;i<=n;i++)
{
q[i]=(x+s[i])%mod;
sum+=q[i];
}
if(!check(ans)) continue;
int l=0,r=sum+1,tmp=-1;
while(l<=r)
{
int mid=(l+r)>>1;
if(check(mid)){tmp=mid;r=mid-1;}
else l=mid+1;
}
if(tmp!=-1) ans=min(ans,tmp);
}
printf("%d",ans);
return 0;
}
8.4考试总结(NOIP模拟30)[毛一琛·毛二琛·毛三琛]的更多相关文章
- 2021.8.4考试总结[NOIP模拟30]
T1 毛衣衬 将合法子集分为两个和相等的集合. 暴力枚举每个元素是否被选,放在哪种集合,复杂度$O(3^n)$.考虑$\textit{meet in the middle}$. 将全集等分分为两部分分 ...
- noip模拟30[毛毛毛探探探]
\(noip模拟30\;solutions\) 所以说,这次被初中的大神给爆了????? 其实真的不甘心,这次考场上的遗憾太多,浪费的时间过多,心情非常不好 用这篇题解来结束这场让人伤心的考试吧 \( ...
- 6.17考试总结(NOIP模拟8)[星际旅行·砍树·超级树·求和]
6.17考试总结(NOIP模拟8) 背景 考得不咋样,有一个非常遗憾的地方:最后一题少取膜了,\(100pts->40pts\),改了这么多年的错还是头一回看见以下的情景... T1星际旅行 前 ...
- 5.23考试总结(NOIP模拟2)
5.23考试总结(NOIP模拟2) 洛谷题单 看第一题第一眼,不好打呀;看第一题样例又一眼,诶,我直接一手小阶乘走人 然后就急忙去干T2T3了 后来考完一看,只有\(T1\)骗到了\(15pts\)[ ...
- 5.22考试总结(NOIP模拟1)
5.22考试总结(NOIP模拟1) 改题记录 T1 序列 题解 暴力思路很好想,分数也很好想\(QAQ\) (反正我只拿了5pts) 正解的话: 先用欧拉筛把1-n的素数筛出来 void get_Pr ...
- 2021.9.17考试总结[NOIP模拟55]
有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...
- [考试总结]noip模拟23
因为考试过多,所以学校的博客就暂时咕掉了,放到家里来写 不过话说,vscode的markdown编辑器还是真的很好用 先把 \(noip\) 模拟 \(23\) 的总结写了吧.. 俗话说:" ...
- noip模拟30
\(\color{white}{\mathbb{缀以无尽之群星点点,饰以常青之巨木郁郁,可细斟木纹叶脉,独无可极苍穹之览,名之以:密林}}\) 看完题后感觉整套题都没什么思路,而且基本上整场考试确实是 ...
- Noip模拟30 2021.8.4
T1 毛一琛 考场上打的稳定的$O((2^n)^2)$的暴力.其实再回忆一下上次那道用二进制枚举的题$y$ 就可以知道一样的道理,使用$\textit{Meet In the Middle}$, 按照 ...
- NOIP 模拟 $30\; \rm 毛三琛$
题解 \(by\;zj\varphi\) 二分答案,考虑二分背包中的最大值是多少. 枚举 \(p\) 的值,在当前最优答案不优时,直接跳掉. 随机化一下 \(p\),这样复杂度会有保证. Code # ...
随机推荐
- docker 应用篇————容器共享数据卷[十五]
前言 简单介绍一下多个容器间容器卷共享. 正文 先启动上一节的test:2.0 这个镜像. docker run --name test01 -it test:2.0 /bin/bash 然后 ctr ...
- c# Barrier 线程回调
前言 假如现在有一个这样的需求,我一堆小黄人生产小黄丹,而大黄人要一直吃小黄丹. 如果是这样的话,想到就是一堆小黄人作为一个多线程,然后一直制造,然后另外一个大黄人一直检索是否有小黄丹,有就吃掉. 但 ...
- 【笔记】问题控制与管理&故障、问题、已知错误、变更请求之间的逻辑关系&问题管理流程
[笔记]问题控制与管理&故障.问题.已知错误.变更请求之间的逻辑关系 问题控制与管理 与故障管理的尽可能快地恢复服多的目标不同,问题管理是要防止再次发生故障 例如你制作了一个报表,用户填写了问 ...
- 力扣485(java)-最大连续数1的个数(简单)
题目: 给定一个二进制数组, 计算其中最大连续 1 的个数. 示例: 输入:[1,1,0,1,1,1]输出:3解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3. 提示: 输入 ...
- HarmonyOS NEXT应用开发案例—状态栏显隐变化
介绍 本示例介绍使用Scroll组件的滚动事件 onScroll 实现状态栏显隐变化.该场景多用于各种软件的首页.我的等页面中. 效果预览图 使用说明 加载完成后显示状态栏显隐变化页面,上下拖动屏幕, ...
- HarmonyOS NEXT应用开发—翻页动效案例
介绍 翻页动效是应用开发中常见的动效场景,常见的有书籍翻页,日历翻页等.本例将介绍如何通过ArkUI提供的显示动画接口animateTo实现翻页的效果. 效果图预览 使用说明 本例通过setInter ...
- StarLake:汇量科技云原生数据湖的探索和实践
简介: 快速了解汇量科技在云原生数据湖领域的探索和实践,详解 StarLake 的架构及业务应用案例. 作者:陈绪(汇量科技资深算法架构师,EnginePlus 2.0 产品负责人) 内容框架: 互联 ...
- EDAS 4.0 助力企业一站式实现微服务架构转型与 K8s 容器化升级
简介: EDAS 正式来到 4.0 时代,发布多项重磅新能力:同时联合新产品-云原生应用设计开发平台 ADD 1.0,一起发布云原生应用研发&运维 PaaS 产品家族,助力企业应用架构现代化 ...
- WPF 一千个矩形做动画测试性能
在很多性能测试开始之前,都需要测试一下自己的期望优化的设备的性能上限是多少.我每次都是重新写一个测试应用,因为每次需要优化的方向都不相同.本文将记录一个我写的一个简单的测试应用,这里面包含了一千个半透 ...
- "友链"
欢迎来到我的友链小屋 展示本站所有友情站点,排列不分先后,均匀打乱算法随机渲染的喔! 友链信息 博客名称:麋鹿鲁哟博客网址:https://www.cnblogs.com/miluluyo/博客头 ...