高一下三调|ssy的队列|hash dp|题解

news/2024/10/9 18:21:54

image
image
SSY的队列题目链接

解析:

考场上看到这个题第一眼是绝望的,毕竟数论咱是一窍不通.
但是往下细看了看这个数据范围,N是很小的,就想了想模拟.
然而只骗到10分.
这个题绩效较高的解法是状压dp,在N<15的范围之内均可薄纱(ppllxx_9G也是成功拿到这70 rank 1了 orz),可得70,但是一到后面三个点就是RE了.
虽说非正解,但也是借这个题又回顾了一下我们的状压dp.
状压代码:

#include<bits/stdc++.h>
#define ll long long
#define qr qr()
using namespace std;inline ll qr
{ll x=0;char ch=getchar();bool f=1;while(ch>57||ch<48){if(ch=='-')f=0;ch=getchar();}while(ch>=48&&ch<=57)x=(x<<3)+(x<<1)+ch-48,ch=getchar();if(f)return x;else return ~(x-1);
}
const int mod=1234567891;
ll n,m,num[31],f[1<<17][17],ans;
bool vis[17][17];
void init()
{n=qr;for(int i=1;i<=n;++i)num[i]=qr;putchar('\n');m=qr;for(int i=1;i<=n;++i){for(int j=1;j<i;++j){if(abs(num[i]-num[j])%m)vis[i][j]=vis[j][i]=1;}}for(int i=0;i<n;++i)f[(1<<i)][i]=1;for(int i=1;i<(1<<n);++i){//状压枚举状态 我们每次都是在整个状态的末尾加新的人 for(int now=0;now<n;++now){//枚举站在最末尾的人 if((1<<now)&i){//这个人在状态内 for(int man=0;man<n;++man){//枚举新加入的人 if(((1<<man)&i));else if(vis[man+1][now+1])f[i|(1<<man)][man]=(f[i|(1<<man)][man]+f[i][now])%mod;}}}} for(int i=0;i<n;++i)ans=(ans+f[(1<<n)-1][i])%mod;printf("%lld",ans);
}
int main()
{freopen("ssy.in","r",stdin);freopen("ssy.out","w",stdout); init();return 0;
} 

正解思路十分奇妙,我们观察题目的描述,意思是所有对M余数相等的数是不可放在一起的.
那么我们可以将所有的数以余数分类,再进行处理.
可知:
1.同类数不可以放在一起,但是同类数的位置均可对调.
2.我们定义的某个状态的种类数,事实取决于某个状态不同种类的不同剩余个数的情况.
第二条是较难归纳出的,我们来看一个浅显的例子:
2233这四个数进行排列的种类数与4455这四个数排列的情况数是一致的.
状压为什么会炸,因为它存了很多没有用的状态而且也访问并转移了许多没有用的状态.
同时因为它没有类别之分,就会导致很多时候它的一些状态是已经访问过的,但状压无法辨识.
如此看状压已经没有优化空间,但是状压的思路我们要留着.
接着看如何实现.
我们根据上述规律去走一遍dfs,只不过这次不是单纯的暴力模拟了,我们加入了记搜,状压,以及hash成分.
为什么还有hash呢,因为我们想想,dfs依旧以着dp的思路在跑.
然而我们的dp描述状态要各个数余下的种类以及最后一个数是哪一种的(因为明显我们是不可以把两个同种的放在一起的).
但是它有三十个数,所以明显咱们不能开三十维.
那就要借助一个hash的思想,将状态压成一个ull的数,同时用map将这个数映射到一个可以操作的下标上.
这样就能保证转移有效,省去空间,同时得到正解.

正解:

#include<bits/stdc++.h>
#define ll long long
#define llu unsigned long long
using namespace std;const int N=50,mod=1234567891,mode=131;
//        种类数↓  ↓每个种类中所含数. 
int n,num[N],m,tot,all[N],nowleft[N],mx;
//                           ↑未被操作的剩下个数为相应大小的种类的个数. 
bool vis[N];
map <llu,ll> mp[N];//用map实现记忆化,保证重复状态不重搜. 
ll ans,pw[N];
//                 ↓最后一个数是哪一种的. 
ll dfs(int now,int lst)
{//        ↑填到第几个数 if(now>n)//边界是所有数都已填入. return 1;memset(nowleft,0,sizeof(nowleft));for(int i=1;i<=tot;++i)if(i^lst)++nowleft[all[i]];llu nzt=all[0];for(int i=1;i<=mx;++i)//个数为0的种类不必存入状态中. nzt=nzt*mode+nowleft[i];nzt=nzt*mode+all[lst]; if(mp[now].find(nzt)!=mp[now].end())return mp[now][nzt];//已经访问过的状态不再搜. ll nans=0;if(all[0]){--all[0];nans=(nans+dfs(now+1,0))%mod;++all[0];}for(int i=1;i<=tot;++i){if((i^lst)&&all[i]){--all[i];nans=(nans+dfs(now+1,i))%mod;++all[i];}}return mp[now][nzt]=nans;//记忆化 
}
void init()
{scanf("%d",&n);for(int i=1;i<=n;++i){scanf("%d",&num[i]);}scanf("%d",&m);for(int i=1;i<=n;++i)num[i]=(num[i]%m+m)%m;for(int i=1;i<=n;++i){if(vis[i])continue;vis[i]=1;int cnt=0;for(int j=i;j<=n;++j){if(num[i]^num[j]);else vis[j]=1,++cnt;}mx=max(mx,cnt);if(cnt==1)++all[0];else all[++tot]=cnt;}pw[0]=1;mx=max(all[0],mx);for(int i=1;i<=mx;++i)pw[i]=pw[i-1]*i%mod;ans=1;for(int i=0;i<=tot;++i)ans=ans*pw[all[i]]%mod;ans=ans*dfs(1,0)%mod;printf("%lld",ans);
}
int main()
{freopen("ssy.in","r",stdin);freopen("ssy.out","w",stdout); init();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/27890.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

Git——关于Git的一些补充(1)

Git——关于Git的一些补充(1) 提示:图床在国外且动图比较多的情况下,需要时间加载。 目录: 目录Git——关于Git的一些补充(1)提示:图床在国外且动图比较多的情况下,需要时间加载。目录:Git基础Git文件的生命周期Git文件的存储空间的划分Git安装过程补充说明Git的撤销…

UHF RFID 使用小记

1,概念 UHF:Ultra High Frequency;超高频。 RFID:Radio Frequency Identification;射频识别。 电子标签:即RFID标签,是RFID的俗称。 PDA:Personal Digital Assistant;个人数字助理。 发卡器:对卡进行读写操作的工具。 EPC:Electronic product code;电子产品代码。 …

文学作品|在线阅读

分享文字和音频类的文学作品,陶冶情操,宣传正能量。#wh-tab{font-size:20px;text-align:center;}a:link {text-decoration: none;}td{font-size: 16px;text-align:center;}td:empty:after{content:虚位以待;color:grey;} 前言 若有空,将古今中外的常见文学作品挂载在网络上,…

[转]ptp(precision time protocol)时钟同步

一、介绍1:什么是ptpPTP(Precision Time Protocol) 是一个通过网络同步时钟的一个协议。当硬件支持时,PTP 精度能达到亚微秒,比 NTP(Network Time Protocol)精度更高。 2:ptp应用场景1)数据中心数据中心需要NTP/PTP同步,以确保集群的时域运行。同步对于虚拟机计算是必不…

3. SpringBoot 整合第三方技术

1. 整合Junit 一般来说是不需要进行处理的 ,因为在创建SpringBoot 工程时 ,会自动整合junit​的 要说怎么配置的话?也可以写一下相关的配置:以下就是SpringBoot 整合 Junit 相关步骤导入相关依赖 <dependency><groupId>org.springframework.boot</groupId&g…

5.5

推一下手机壁纸

[转]IRIG-B码授时工作原理

在授时设备中有一种是B码授时的,但是大部分人不太清楚何为B码授时?这种类型的授时工作原理是怎么样? 首先我们要知道什么是B码,然后再介绍它的授时工作原理,B码是一种电力术语,它是IRIG-B码的通俗叫法,英文全称是inter-range instrumentationgroup-B,是在2020年公布的电…

2024 年12个好用的开源 Wiki 软件工具盘点

Wiki是一个集中式的、基于网络的平台,使员工可以轻松地访问和记录信息。简单来说,它是一个可靠信息的统一来源。在任何成功的公司中,部门间的知识共享是至关重要的。如果没有一个简单的信息交流方法,团队怎样才能有效合作呢?Wiki软件提供了一种创建、组织及在全公司范围内…