最有名的莫过于想死一次吗。

前言

至今都不知道题目是个啥。。。

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)[毛一琛·毛二琛·毛三琛]的更多相关文章

  1. 2021.8.4考试总结[NOIP模拟30]

    T1 毛衣衬 将合法子集分为两个和相等的集合. 暴力枚举每个元素是否被选,放在哪种集合,复杂度$O(3^n)$.考虑$\textit{meet in the middle}$. 将全集等分分为两部分分 ...

  2. noip模拟30[毛毛毛探探探]

    \(noip模拟30\;solutions\) 所以说,这次被初中的大神给爆了????? 其实真的不甘心,这次考场上的遗憾太多,浪费的时间过多,心情非常不好 用这篇题解来结束这场让人伤心的考试吧 \( ...

  3. 6.17考试总结(NOIP模拟8)[星际旅行·砍树·超级树·求和]

    6.17考试总结(NOIP模拟8) 背景 考得不咋样,有一个非常遗憾的地方:最后一题少取膜了,\(100pts->40pts\),改了这么多年的错还是头一回看见以下的情景... T1星际旅行 前 ...

  4. 5.23考试总结(NOIP模拟2)

    5.23考试总结(NOIP模拟2) 洛谷题单 看第一题第一眼,不好打呀;看第一题样例又一眼,诶,我直接一手小阶乘走人 然后就急忙去干T2T3了 后来考完一看,只有\(T1\)骗到了\(15pts\)[ ...

  5. 5.22考试总结(NOIP模拟1)

    5.22考试总结(NOIP模拟1) 改题记录 T1 序列 题解 暴力思路很好想,分数也很好想\(QAQ\) (反正我只拿了5pts) 正解的话: 先用欧拉筛把1-n的素数筛出来 void get_Pr ...

  6. 2021.9.17考试总结[NOIP模拟55]

    有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...

  7. [考试总结]noip模拟23

    因为考试过多,所以学校的博客就暂时咕掉了,放到家里来写 不过话说,vscode的markdown编辑器还是真的很好用 先把 \(noip\) 模拟 \(23\) 的总结写了吧.. 俗话说:" ...

  8. noip模拟30

    \(\color{white}{\mathbb{缀以无尽之群星点点,饰以常青之巨木郁郁,可细斟木纹叶脉,独无可极苍穹之览,名之以:密林}}\) 看完题后感觉整套题都没什么思路,而且基本上整场考试确实是 ...

  9. Noip模拟30 2021.8.4

    T1 毛一琛 考场上打的稳定的$O((2^n)^2)$的暴力.其实再回忆一下上次那道用二进制枚举的题$y$ 就可以知道一样的道理,使用$\textit{Meet In the Middle}$, 按照 ...

  10. NOIP 模拟 $30\; \rm 毛三琛$

    题解 \(by\;zj\varphi\) 二分答案,考虑二分背包中的最大值是多少. 枚举 \(p\) 的值,在当前最优答案不优时,直接跳掉. 随机化一下 \(p\),这样复杂度会有保证. Code # ...

随机推荐

  1. javascript现代编程系列教程之X——javascript人工智能

    JavaScript 在人工智能(AI)领域的应用主要体现在以下几个方面: 浏览器端的机器学习:TensorFlow.js 是一个在浏览器中运行的 JavaScript 机器学习库,它允许开发者训练和 ...

  2. Oracle sql 月份的加减以及差值

    Oracle sql 月份的加减以及差值 差值 使用months_between,输出的是两个日期的差值 select months_between(TO_DATE('2022-05-31','yyy ...

  3. 力扣43(java)-字符串相乘(中等)

    题目: 给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式. 注意:不能使用任何内置的 BigInteger 库或直接将输入 ...

  4. 通过 MSE 实现基于Apache APISIX的全链路灰度

    简介: 无论是微服务网关还是微服务本身都需要识别流量,根据治理规则做出动态决策.当服务版本发生变化时,这个调用链路的转发也会实时改变.相比于利用机器搭建的灰度环境,这种方案不仅可以节省大量的机器成本和 ...

  5. 当 TiDB 与 Flink 相结合:高效、易用的实时数仓

    简介: 利用实时数仓,企业可以实现实时 OLAP 分析.实时数据看板.实时业务监控.实时数据接口服务等用途.但想到实时数仓,很多人的第一印象就是架构复杂,难以操作与维护.而得益于新版 Flink 对 ...

  6. [PHP] Laravel 的 503 Service Unavailable 模板提示的来源

    当我们看到 Laravel 的 503 样式的模板时,是启用维护模式的时候的提示(php artisan down). 开启访问运行 php artisan up. Refer:Laravel 503 ...

  7. dotnet 警惕 ConcurrentDictionary 使用 FirstOrDefault 获取到非预期的首项

    在 dotnet 里面的 ConcurrentDictionary 是一个支持并发读写的线程安全字典,在这个字典里面有一些行为会出现随机性,即多次执行相同的代码返回的结果可能不相同.本文记录在 Con ...

  8. dotnet 使用 FormatterServices 的 GetUninitializedObject 方法在丢失 DLL 情况下能否执行

    在 dotnet 里面,可以使用 FormatterServices 的 GetUninitializedObject 方法可以实现只创建对象,而不调用对象的构造函数方法.而如果在使用此方法时,存在了 ...

  9. vue中vant-list组件实现下拉刷新,上滑加载

    后端返回的数据是一股脑的情况(不是按pageSize,pageNum一组一组的发送)时,前端使用vant-list实现懒加载需要再写一点js,记录一下 main.js: Vue.use(List); ...

  10. 自动生成robot自动化测试用例

    背景:java项目使用swagger管理接口,随着需求的开发接口也有增加,要从swagger界面中去查找出新增的接口是件很费时,效率很低的事情. 适用情况: java项目且适用swagger管理接口 ...