首页 > 其他分享 >23.4.15 NOIP2010提高游记

23.4.15 NOIP2010提高游记

时间:2023-04-15 16:44:06浏览次数:37  
标签:监狱 ch 15 NOIP2010 int 查集 23.4 ans include

第一次做提高,之前做的都是普及,还是感觉挺难的,心态有点裂开。

1.机器翻译

这题首先一看就是一道模拟题目,要注意的是字典的内存问题,在超内存以后要减1,直接上代码 :-) ,时间复杂度O(n)

 1 #include<bits/stdc++.h>
 2 #pragma GCC opzimize(3)
 3 using namespace std;
 4 inline long long read(){
 5     long long ans=0,f=1;
 6     char ch=getchar();
 7     if(ch=='-'){
 8         f=-1;
 9     }
10     while(!isdigit(ch)){
11         ch=getchar();
12     }
13     while(isdigit(ch)){
14         ans=((ans<<1)+(ans<<3)+(ch^48));
15         ch=getchar(); 
16     }
17     return ans*f;
18 }
19 int main(){
20     queue<int> q;
21     int m=read(),n=read(),ans;
22     bool inq[1010];
23     for(int i=1;i<=n;i++){
24         int x=read();
25         if(inq[x])continue;
26         else{
27             if(q.size()>=m){
28                 inq[q.front()]=false;
29                 q.pop();
30             }
31             q.push(x);
32             inq[x]=true;
33             ans++;
34         }
35     }
36     cout<<ans;
37     return 0;
38 }

2.乌龟棋

一拿到这题就想到是一道DP题,首先推状态转移方程,F[i][j][k][l]表示走后分数的状况,因为有4个维度可以推出不同的情况,则有

 1 if(i){
 2 f[i][j][k][l]=max(f[i][j][k][l],f[i-1][j][k][l]+a[s]);
 3 }
 4 if(j){
 5 f[i][j][k][l]=max(f[i][j][k][l],f[i][j-1][k][l]+a[s]);
 6 }
 7 if(k){
 8 f[i][j][k][l]=max(f[i][j][k][l],f[i][j][k-1][l]+a[s]);
 9 }
10 if(l){
11 f[i][j][k][l]=max(f[i][j][k][l],f[i][j][k][l-1]+a[s]);
12 }

综合一下4重循环,代码就出来了

 1 f[0][0][0][0]=a[1];//记得把起始点加进去
 2 for(int i=0;i<=b[1];i++){
 3     for(int j=0;j<=b[2];j++){
 4         for(int k=0;k<=b[3];k++){
 5             for(int l=0;l<=b[4];l++){
 6                 s=i+j*2+k*3+l*4+1;
 7                 if(i){
 8                     f[i][j][k][l]=max(f[i][j][k][l],f[i-1][j][k][l]+a[s]);
 9                 }
10                 if(j){
11                     f[i][j][k][l]=max(f[i][j][k][l],f[i][j-1][k][l]+a[s]);
12                 }
13                 if(k){
14                     f[i][j][k][l]=max(f[i][j][k][l],f[i][j][k-1][l]+a[s]);
15                 }
16                 if(l){
17                     f[i][j][k][l]=max(f[i][j][k][l],f[i][j][k][l-1]+a[s]);
18                 }
19                 f[i][j][k][l]+=a[s];
20             }
21         }
22     }
23 }

下面是完整版的代码,时间复杂度最大O(40^4)

 1 #include<bits/stdc++.h>
 2 #define N 360
 3 #define M 5
 4 using namespace std; 
 5 int a[N],b[M],f[41][41][41][41];
 6 int main(){
 7     int n,m,s=0;
 8     cin>>n>>m;
 9     for(int i=1;i<=n;i++){
10         cin>>a[i];
11     } 
12     for(int i=1;i<=m;i++){
13         int pp;
14         cin>>pp;
15         b[pp]++;
16     }
17     f[0][0][0][0]=a[1];
18     for(int i=0;i<=b[1];i++){
19         for(int j=0;j<=b[2];j++){
20             for(int k=0;k<=b[3];k++){
21                 for(int l=0;l<=b[4];l++){
22                     s=i+j*2+k*3+l*4+1;
23                     if(i){
24                         f[i][j][k][l]=max(f[i][j][k][l],f[i-1][j][k][l]+a[s]);
25                     }
26                     if(j){
27                         f[i][j][k][l]=max(f[i][j][k][l],f[i][j-1][k][l]+a[s]);
28                     }
29                     if(k){
30                         f[i][j][k][l]=max(f[i][j][k][l],f[i][j][k-1][l]+a[s]);
31                     }
32                     if(l){
33                         f[i][j][k][l]=max(f[i][j][k][l],f[i][j][k][l-1]+a[s]);
34                     }
35                     f[i][j][k][l]+=a[s];
36                 }
37             }
38         }
39     }
40     cout<<f[b[1]][b[2]][b[3]][b[4]]/2;
41     return 0;
42 }

到这儿,接下来就是考场上没做的了qwq


 

3.关押罪犯

读题可以发现,我们需要通过哪些人应该在不同的监狱来倒推出哪些人应该在相同的监狱,所以想到用并查集来维护。

本题需要用到种类并查集来维护A监狱和B监狱,这题有贪心的雏形,在对怨气值排序后,我们可以让怨气值最大的一对犯人分别在两个监狱,如果A为B的敌人,那就去另一个监狱,反之就在一个监狱。当A与B、C皆为敌人时,此时就为最小影响力了,因为排序保证了单调递减性。

Question:为什么本题不用并查集,而用种类并查集呢?

Answer:一般的并查集,维护的是具有连通性、传递性的关系,例如亲戚的亲戚是亲戚。但是,有时候,我们要维护另一种关系:敌人的敌人是朋友。种类并查集就是为了解决这个问题而诞生的。所以我们要用种类并查集来解决这个问题。

所以本题内我们还要注意敌人的敌人是朋友这一关系,所以当A和B为敌人,B和C为敌人时,A与C在没有说明是敌人的情况下是朋友关系,所以这时我们能把C放在A所在的监狱去。

我们就可以得到一种类似于跳板的东西,例如 A->B->C->D中(“->”在这里表示仇恨关系),A可以和C、D在一起,B可以和D在一起、C可以和A在一起,D可以和B在一起。所以我们就可以得到一种安全的方案,即为a[A,C] and b[B,D]。就可以发现,只要在关系中成线性结构,便可以得到一个安全关系。但是如果出现了环,则有冲突事件的必然发生,所以我们得到了一种新作法,判断是否有环。

注意!没有要输出0!

Code:并查集

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<iomanip>
 4 #include<algorithm>
 5 #define rg register int//卡常
 6 
 7 using namespace std;
 8 
 9 struct su{
10     int f,t,v;
11 }a[100010];
12 
13 int n,m,l,r,mid,f;
14 int s[20001<<1]; //不要单独开两数组!
15 
16 inline int qr(){  char ch; //快读
17     while((ch=getchar())<'0'||ch>'9');
18     int res=ch^48;
19     while((ch=getchar())>='0'&&ch<='9')
20         res=res*10+(ch^48);
21     return res;
22 }
23 
24 inline bool cmp(su x,su y){
25     return x.v>y.v; //从大到小排序
26 }
27 
28 inline int get(int x){
29     if(x==s[x])return x;
30     return s[x]=get(s[x]);//路径压缩
31 }
32 
33 int main(){
34     n=qr(),m=qr();
35     for(rg i=1;i<=m;++i)
36         a[i].f=qr(),a[i].t=qr(),a[i].v=qr();
37     sort(a+1,a+m+1,cmp); //贪心
38     for(rg i=1;i<=n;++i)
39         s[i]=i,s[i+n]=i+n; //初始化不能忘!!!
40     for(rg i=1;i<=m;++i){
41         rg x=a[i].f,y=a[i].t;
42         if(get(x)==get(y)||get(x+n)==get(y+n)){
43             f=a[i].v;break;//不能在同一监狱的仇人撞上了
44         }
45         s[s[x+n]]=s[y];
46         s[s[x]]=s[y+n];//维护两罪犯在不同监狱的关系
47     }printf("%d\n",f);
48     return 0;
49 }

 

标签:监狱,ch,15,NOIP2010,int,查集,23.4,ans,include
From: https://www.cnblogs.com/dabianche2008/p/23_4_15.html

相关文章

  • Lenovo Legion 5 15IMH05H电脑 Hackintosh 黑苹果efi引导文件
    原文来源于黑果魏叔官网,转载需注明出处。(下载请直接百度黑果魏叔)硬件型号驱动情况主板LenovoLegion515IMH05H处理器Intel(R)Core(TM)[email protected]已驱动内存16GB2933MHzDDR4已驱动硬盘Intel760p512GB已驱动显卡Intel(R)UHDGraphics630(1GB)......
  • LeetCode 115. 不同的子序列
    classSolution{public:longlongf[1010][1010];//f[i][j]表示s前i个字符得到t前j个字符的所有方案intnumDistinct(strings,stringt){f[0][0]=1;intn=s.size(),m=t.size();s=''+s;t=''+t;for(inti=1;i<=n;i+......
  • 【流水】2023.04.15
    省选了,省选完了,省选出分了令人意外的是殷教退了当时我,zas,mizuki,2k22,crs都不信但是是真的看到gtm进了似乎kaguya和joke没进最近数学在开排列组合实验的水平也就我当年那样(笑或许比我强不少?不清楚但是格路计数\(\binom{n+m}{m}\)在做学案的时候没一个人会也是真的。期待......
  • 15.Proxysql读写分离搭建
    Proxysql读写分离搭建1)环境准备这里分别准备四台虚拟机,192.168.10.129(server_id:1293306) 192.168.10.130(server_id:1303306) 192.168.10.131(server_id:1313306) 192.168.10.132,192.168.10.129~131这三台都装好mysql服务端,且配置好主从复制,我这里主库是12......
  • [leetcode每日一题]4.15
    1042. 不邻接植花提示中等181相关企业有 n 个花园,按从 1 到 n 标记。另有数组 paths ,其中 paths[i]=[xi,yi] 描述了花园 xi 到花园 yi 的双向路径。在每个花园中,你打算种下四种花之一。另外,所有花园 最多 有 3 条路径可以进入或离开.你需要为每个花园选择一......
  • 建民打卡日记4.15
    五本新书,借给a,b,c三人,每人借一本,共有多少种借书方案?二、设计思路1.从五个数中选取三个排列组合,确立循环范围2.建立循环穷举所有情况3.符合条件的情况输出三、程序流程图  四、代码实现#include<iostream>usingnamespacestd;intmain(){ inta,b,c,i=0;......
  • CF1592F2 题解
    题意传送门给定一个\(n\)行\(m\)列的目标矩阵,矩阵元素只有W或B,并且你有一个初始矩阵,元素全为W。现在你可以矩阵实施以下操作:使用一块钱,选定一个包含\((1,1)\)的子矩阵,把矩阵中的元素全部反转(W变B,B变W)。使用三块钱,选定一个包含\((n,1)\)的子矩阵,把矩阵......
  • C/C++人事信息系统[2023-04-15]
    C/C++人事信息系统[2023-04-15]课程设计题目1——链表综合算法设计一、设计内容已知简单的人事信息系统中职工记录包含职工编号(no)、职工姓名(name)部门名称(depname)、职称(title)和工资数(salary)等信息,设计并完成一个简单的人事信息管理系统,要求完成但不限于以下功能:(1)......
  • C/C++校园导航图[2023-04-15]
    C/C++校园导航图[2023-04-15]课程设计题目2——校园导航图的实现一、设计内容(1)设计一个学校的校园平面图,所选结点不少于30个。以图中顶点表示校园各景点,存放景点名称、代号、简介等信息;以边表示路径,存放路径长度等相关信息。(2)为来往客人提供图中任意景点相关信息的查询......
  • C/C++校园管理系统[2023-04-15]
    C/C++校园管理系统[2023-04-15]校园管理系统(100分)1.系统界面设计(5分)(1)登录界面。该界面实现系统的登录。(1分)(2)系统主界面。该界面应该包含链接到各个二级子功能的菜单,提供进入二级栏目(1分)(3)各个子功能界面。该界面应该能够实现对数据的各种操作,并实现返回上一......