P3451旅游景点 Tourist Attractions

这个代码其实不算是正规题解的(因为我蒟蒻)是在我们的hzoj上内存限制324MIB情况下过掉的,而且经过研究感觉不太能用滚动数组,所以那这个题学习一下状压dp思想还是勉强可以的


  1 /*
2 (可以不看)
3 (窃窃地)废话:
4 想了半天还是写一篇题解吧,尽管有点麻烦。。。。
5 但这题的确做了不下十几节课。。。。。
6 不写一篇对不起这几天牺牲的公自了(惨)
7 */
8 #include<bits/stdc++.h>
9 using namespace std;
10 const int NN=200005,MM=20005;
11 int n,m,q,k;
12 struct SNOW{
13 int to,next,value;
14 }e[NN<<1];
15 int r[NN<<1],tot=0;
16 int dis[25][MM],a[25];
17 bool v[MM];
18 int dp[1<<20][25];
19 struct snow{
20 int q,data;
21 friend bool operator<(snow a,snow b){return a.data>b.data;}
22 };
23 snow cc; priority_queue<snow> Q;
24 inline void add(int x,int y,int z){
25 e[++tot]=(SNOW){y,r[x],z};
26 r[x]=tot;
27 }
28 inline void WSN(int st){
29 int x,y;
30 cc.q=st ;cc.data=0;
31 Q.push(cc);
32 memset(v,false,sizeof(v));//一定记得bool数组清零,这就是你调了一个大会还没过的错误。。。。。。。。。
33 dis[st][st]=0;
34 while(!Q.empty()){
35 x=Q.top().q;y=Q.top().data;
36 Q.pop();
37 if(!v[x]){
38 v[x]=true;
39 for(int i=r[x];i;i=e[i].next){
40 cc.q=e[i].to;
41 if(dis[st][cc.q]>y+e[i].value){
42 dis[st][cc.q]=y+e[i].value;
43 cc.data=dis[st][cc.q];
44 Q.push(cc);
45 }
46 }
47 }
48 }
49 }
50 inline void init(){
51 dp[0][1]=0;
52 for(int i=2;i<=k+1;i++)
53 if(!a[i]) dp[1<<(i-2)][i]=dis[1][i];
54 }
55 inline int read(){
56 int x=0,f=1; char ch=getchar();
57 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
58 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar();}
59 return x*f;
60 }
61 void write(int x){
62 if(x<0){ putchar('-'); x=-x;}
63 if(x>9) write(x/10);
64 putchar(x%10+'0');
65 }
66 signed main(void)
67 {
68 memset(dis,50,sizeof(dis));//数组都要开小一点,否则会爆炸(你调了两天才发现的。。。。)
69 n=read(),m=read(),k=read();
70 int mzs=1<<k;
71 for(int i=1;i<=m;i++)
72 {
73 int x=read(),y=read(),z=read();
74 add(x,y,z); add(y,x,z);
75 }
76 if(k==0) { WSN(1); write(dis[1][n]); putchar('\n'); return 0;}
77 for(int i=1;i<=k+1;i++) WSN(i);
78 q=read();
79 for(int i=1;i<=q;i++)
80 {
81 int f=read(),l=read();
82 if(f>(k+1)||l>(k+1)) continue;
83 a[l]|=(1<<(f-2));//找到具有较高优先级的位置并赋值为 1
84 }
85 memset(dp,50,sizeof(dp));
86 init();
87 for(int i=0;i<mzs;i++)//循环找1
88 for(int j=0;j<k;j++)//循环起点
89 for(int u=0;u<k;u++)//循环终点
90 {
91 if((i&(1<<j))==0) continue;
92 if((i&(1<<u))==0 && (i|a[u+2])==i/*如果有优先级的点不包含在i情况下就跳过*/ )
93 dp[i|(1<<u)][u+2]=min(dp[i|(1<<u)][u+2],dp[i][j+2]+dis[j+2][u+2]);
94 //dp[i][j]表示i状态下经过的中间城市的编号
95 }
96 int wsn=0x3fffffff;
97 for(int i=2;i<=k+1;i++)
98 wsn=min(wsn,dp[(1<<k)-1][i]+dis[i][n]);
99 write(wsn); putchar('\n');
100 return 0;
101 }//思想:分裂做法。
102 //将整个图分裂成1~(2~k+1)和(2~k+1)~n,如下图
103 /*
104 2
105 |
106 |
107 |
108 |
109 |
110 1 | n
111 |
112 |
113 |
114 |
115 k+1
116 dp的部分是前面的半张图,而后面的半张图用最后的循环搞定即可(第89,90行代码处)
117 其他的注释很清楚了
118 */
 

P3622动物园

人生中第二篇题解,因为这题的确很喵~怎么说呢,感觉不用赋值最小值(用的用的)。。。算了代码里说的挺清楚,这里就不叨叨那么多了(思路在题解最后)

 1 #include<bits/stdc++.h>
2 #define int long long
3 using namespace std ;
4 const int MM =10005;
5 int N,C,snow,mzs=(1<<5);
6 int dp[ MM ][(1<<5)+5],wsn[ MM ][(1<<5)+5];
7 //表示起点为i的五个数字(及小朋友可以看到的动物)
8 //在一定的状态下可以使小朋友开心的个数(由此可见夜聊的好处~//^v^//~)
9 // dp[i][j]=min(dp[i][j],dp[i][j]+wsn[i][j]);
10 inline int read (){
11 int x=0,f=1; char ch=getchar();
12 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
13 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar();}
14 return x*f;
15 }
16 void write(int x){
17 if(x<0){ putchar('-'); x=-x;}
18 if(x>9) write(x/10);
19 putchar(x%10+'0');
20 }
21 signed main()
22 {
23 N=read(),C=read();
24 for(int i=1;i<=C;i++)
25 {
26 int E=read(),F=read(),L=read(),hate=0,like=0;
27 for(int j=1;j<=F;j++)hate|=1<<((read()-E+N)%N);
28 for(int j=1;j<=L;j++)like|=1<<((read()-E+N)%N);//这一步可以,往下找if判断快乐条件
29 for(int j=0;j<mzs;j++) if( (like&j) || (hate&~j) ) wsn[E][j]++;
30 }
31 for(int l=0;l<mzs;l++)//大的循环枚举不同的开始状态,因为是环,要用每个为开始状态进行找最值,因为最后会转回来(即有重复)
32 {
33 for(int r=0;r<=32;r++) dp[0][r]=-999999999;
34 dp[0][l]=0;
35 for(int i=1;i<=N;i++)
36 for(int j=0;j<mzs;j++)
37 {
38 int k=((j&~(1<<4))<<1);//K是把原来的五位二进制数首位取零,并向左移动一位(其实与(j&15)<<1一样)
39 int u=(k|1);// U是列举移动一位后最右一位的另一种情况(分别为0,1。0的情况既是k,u是1)
40 dp[i][j]=max(dp[i-1][k],dp[i-1][u])+wsn[i][j];
41 }
42 snow=max(snow,dp[N][l]);//在情况内寻找最大值
43 }
44 write(snow); putchar('\n');
45 return 0;
46 }/*思路一:需要预处理:
47 将三种情感看作两两匹配的,及喜欢和中性为一组,讨厌和中性为一组。
48 进行预处理时分开处理,可以解决三进制无法实现的问题。
49 思路二:dp如何做:
50 在循环的时候每次将五位二进制数首位改成零,然后再向左移动一位,
51 表示状态向左转移了一位(这样不用处理环)然后再将新增加的一位
52 分别用0,1表示不同的情况,比较出最大值,在加上当前状态可以有
53 的小朋友数(代码中的解释也十分详细)。
54 */
 

状压dp学习笔记(紫例题集)的更多相关文章

  1. 状压DP学习笔记

    有的时候,我们会发现一些问题的状态很难直接用几个数表示,这个时候我们就会用到状压dp啦~~. 状压就是状态压缩,就是讲原本复杂难以描述的状态用一个数或者几个数来表示qwq.状态压缩是一个很常用的技巧, ...

  2. MMM 状压dp学习记

    状压dp学习记 by scmmm 开始日期 2019/7/17 前言 状压dp感觉很好理解(本质接近于爆搜但是又有广搜的感觉),综合了dp的高效性(至少比dfs,bfs优),又能解决普通dp难搞定的问 ...

  3. 状压DP复习笔记

    前言 复习笔记第4篇.CSP RP++. 引用部分为总结性内容. 0--P1433 吃奶酪 题目链接 luogu 题意 房间里放着 \(n\) 块奶酪,要把它们都吃掉,问至少要跑多少距离?一开始在 \ ...

  4. 动态规划专题(一)——状压DP

    前言 最近,决定好好恶补一下我最不擅长的\(DP\). 动态规划的种类还是很多的,我就从 状压\(DP\) 开始讲起吧. 简介 状压\(DP\)应该是一个比较玄学的东西. 由于它的时间复杂度是指数级的 ...

  5. 状压dp(状态压缩&&dp结合)学习笔记(持续更新)

    嗯,作为一只蒟蒻,今天再次学习了状压dp(学习借鉴的博客) 但是,依旧懵逼·································· 这篇学习笔记是我个人对于状压dp的理解,如果有什么不对的 ...

  6. [学习笔记]状压dp

    状压 \(dp\) 1.[SDOI2009]Bill的挑战 \(f[i][j]\) 表示匹配到字符串的第 \(i\) 位状态为 \(j\) 的方案数 那么方程就很明显了,每次枚举第 \(i\) 位的字 ...

  7. 算法笔记-状压dp

    状压dp 就是把状态压缩的dp 这样还是一种暴力但相对于纯暴力还是优雅的多. 实际上dp就是经过优化的暴力罢了 首先要了解位运算 给个链接吧 [https://blog.csdn.net/u01337 ...

  8. 【状压DP】SCOI2005-洛谷P1896-互不侵犯 (状压例题)

    [状压DP]SCOI2005-洛谷P1896-互不侵犯 (状压例题) 标签(空格分隔): 状压DP 好久没写博客了,真的爽(误) 题目: 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方 ...

  9. 「算法笔记」状压 DP

    一.关于状压 dp 为了规避不确定性,我们将需要枚举的东西放入状态.当不确定性太多的时候,我们就需要将它们压进较少的维数内. 常见的状态: 天生二进制(开关.选与不选.是否出现--) 爆搜出状态,给它 ...

随机推荐

  1. 转:C#根据条件设置datagridview行的颜色

    1 private void LoadData() 2 { 3 DataTable tblDatas = new DataTable(); 4 tblDatas.Columns.Add("I ...

  2. ☕【JVM技术指南】「JVM总结笔记」Java虚拟机垃圾回收认知和调优的"思南(司南)"【下部】

    承接上文 (完结撒花1-52系列)[JVM技术指南]「JVM总结笔记」Java虚拟机垃圾回收认知和调优的"思南(司南)"[上部] 并行收集器 并行收集器(也称为吞吐量收集器)是类似 ...

  3. 【第二篇】- Git 安装配置之Spring Cloud直播商城 b2b2c电子商务技术总结

    Git 安装配置 在使用Git前我们需要先安装 Git.Git 目前支持 Linux/Unix.Solaris.Mac和 Windows 平台上运行. Git 各平台安装包下载地址为:http://g ...

  4. 一文带你了解.Net读写锁

    本文主要讲解.Net基于ReaderWriterLockSlim讲解读写锁 基础概念 读写锁是一个具有特殊用途的线程锁,适用于频繁读取且读取需要一定时间的场景,共享资源的读取操作通常是可以同时执行的, ...

  5. maven编译打包

    sonar扫描java项目,需要使用maven 来到maven项目下第一件事情编译打包,注意代码扫描是在编译之后的:https://blog.csdn.net/qq_34556414/article/ ...

  6. Appium 自动化测试改造思路

    流水账脚本 从头到尾编写测试脚本 PO封装 业务行为与操作具体页面元素分离 basepage封装 如封装find方法,目的时增强稳定性 数据驱动封装 将常用的数据改为配置文件 为构建测试平台打基础

  7. SVN与LDAP服务器整合验证

    说明:svn的访问是以svn://协议访问的,一般都是用http协议访问,所以要使用apache的httpd服务器apache已经添加了对ldap服务器的支持,所以svn的认证过程是使用apache代 ...

  8. MyBatis Plus 批量数据插入功能,yyds!

    最近 Review 小伙伴代码的时候,发现了一个小小的问题,小伙伴竟然在 for 循环中进行了 insert (插入)数据库的操作,这就会导致每次循环时都会进行连接.插入.断开连接的操作,从而导致一定 ...

  9. 一、mybatis入门案例

    今天学习了mybatis框架,简单记录一下mybatis第一个入门案例,目标是使用Mybatis作为持久层框架,执行查询数据的SQL语句并且获取结果集 基本步骤: 物理建模 逻辑建模 引入依赖 创建持 ...

  10. MySQL表空间回收的正确姿势

    不知道大家有没有遇到这样的一种情况,线上业务在MySQL表上做增删改查操作,随着时间的推移,表里面的数据越来越多,表数据文件越来越大,数据库占用的空间自然也逐渐增长 为了缩小磁盘上表数据文件占用的空间 ...