今天听完派队的教学

感觉又可以水几道紫题了

好耶✌

不过想起ygg提到的记忆化搜索

自己其实也是没有搞懂的

还是去做了几道题吧

P2476 [SCOI2008]着色方案

紫题喵

最开始想的是一个这样的状态

f[i][j] 表示的是 第i块板子 前一块用的是编号为j的颜色

其实我们仔细想想就可以想出来 这个状态表示是有会漏情况的 比如1为头的时候

我们再搜3的时候 后面有的情况是有的 但是我们就直接返回了

后来被他们讲到 这就是有后效性 意会一下

一个可做的做法 

我们观察道c1 的数据范围奇小无比 并且抽象一下可以用ci的大小来划分成5种集合 

非常牛逼!

这样我们就可以写出状态转移方程:

f[c1​][c2​][c3​][c4​][c5​][last]=

[c_1 - (last == 2)] * f[c_1 - 1][c_2][c_3[c_4][c_5][1] +[c1​−(last==2)]∗f[c1​−1][c2​][c3​[c4​][c5​][1]+

[c_2 - (last == 3)] * f[c_1 + 1][c_2 - 1][c_3][c_4][c_5][2] +[c2​−(last==3)]∗f[c1​+1][c2​−1][c3​][c4​][c5​][2]+

[c_3 - (last == 4)] * f[c_1][c_2 + 1][c_3 - 1][c_4][c_5][3] +[c3​−(last==4)]∗f[c1​][c2​+1][c3​−1][c4​][c5​][3]+

[c_4 - (last == 5)] * f[c_1][c_2][c_3 + 1][c_4 - 1][c_5][4] +[c4​−(last==5)]∗f[c1​][c2​][c3​+1][c4​−1][c5​][4]+

c_5 * f[c_1][c_2][c_3][c_4 + 1][c_5 - 1][5]c5​∗f[c1​][c2​][c3​][c4​+1][c5​−1][5]

这样子确实是不重不漏的

我们可以这样子理解记忆化搜索:

我们就是在爆搜 但是加了一个不重不漏的集合 来优化

下面的dfs 也是很符合爆搜

就像是在枚举这一位到底填啥 让后根据填的啥规定系数

#include <bits/stdc++.h>
using namespace std;
const int N = 20;
const int M = 1<<16;
const int mod = 1e9+7;
#define int long long
#define LL long long
#define endl '\n'
#define Endl '\n'
#define _ 0
#define inf 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
int n,f[16][16][16][16][16][6],t[6];
int dfs(int a,int b,int c,int d,int e,int last){int &v=f[a][b][c][d][e][last];if(v)return v;if(!a&&!b&&!c&&!d&&!e)return 1;int cnt=0;if(a) cnt=(cnt+(a-(last==2))*dfs(a-1,b,c,d,e,1))%mod;if(b) cnt=(cnt+(b-(last==3))*dfs(a+1,b-1,c,d,e,2))%mod;if(c) cnt=(cnt+(c-(last==4))*dfs(a,b+1,c-1,d,e,3))%mod;if(d) cnt=(cnt+(d-(last==5))*dfs(a,b,c+1,d-1,e,4))%mod;if(e) cnt=(cnt+e*dfs(a,b,c,d+1,e-1,5))%mod;v=cnt%mod;return v;
}
signed main(){fastcin>>n;for(int i=1;i<=n;i++){int x;cin>>x;t[x]++;}cout<<dfs(t[1],t[2],t[3],t[4],t[5],0)<<endl;return ~~(0^_^0);
}

P4850 [IOI2009] 葡萄干 raisins

我们首先来考虑状态如何表示

数据范围只有50 并且切的刀数也是固定的

状态表示就4维就好了 f[x1][x2][y1][y2]表示矩阵类的min 吧

这里和动态规划差不多 属性不一样 dfs 过程也不一样 cnt+= min枚举取min

那我们在考虑爆搜咋写 其实就是枚举横着切 在哪切 竖着在哪切 最后加上自己当前大小的sum

#include <bits/stdc++.h>
using namespace std;
const int N = 55;
const int M = 1<<16;
const int mod = 1e9+7;
#define int long long
#define LL long long
#define endl '\n'
#define Endl '\n'
#define _ 0
#define inf 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
int n,m,f[N][N][N][N],sum[N][N];
int dfs(int x1,int x2,int y1,int y2){if(f[x1][x2][y1][y2])return f[x1][x2][y1][y2];if(x1==x2&&y1==y2)return 0;f[x1][x2][y1][y2]=inf;int cut=sum[x2][y2]-sum[x1-1][y2]-sum[x2][y1-1]+sum[x1-1][y1-1];for(int i=x1;i<x2;i++){f[x1][x2][y1][y2]=min(f[x1][x2][y1][y2],dfs(x1,i,y1,y2)+dfs(i+1,x2,y1,y2));}for(int i=y1;i<y2;i++){f[x1][x2][y1][y2]=min(f[x1][x2][y1][y2],dfs(x1,x2,y1,i)+dfs(x1,x2,i+1,y2));}f[x1][x2][y1][y2]+=cut;return f[x1][x2][y1][y2];
}
signed main(){fastcin>>n>>m;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){int x;cin>>x;sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+x;}}cout<<dfs(1,n,1,m)<<endl;return ~~(0^_^0);
}

P3609 [USACO17JAN]Hoof, Paper, Scissor G

哦 这道题不是记忆化搜索

但是他tag写的记忆化搜索

并且题解也全是记忆化搜索

但是我一眼就是dp啊

就很普通的一个dp

f[i][j][k] 表示我们现在是第i个手势 我们变化了j次 并且上次手势是k

时间复杂度就是O(1e5*20*3) 完全可以通过这道题

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
const int M = 1<<16;
const int mod = 1e9+7;
#define int long long
#define LL long long
#define endl '\n'
#define Endl '\n'
#define _ 0
#define inf 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
int a[N],f[N][22][3];
signed main(){fastint n,m;cin>>n>>m;for(int i=1;i<=n;i++){char c;cin>>c;if(c=='H')a[i]=0;else if(c=='S')a[i]=1;else a[i]=2;}for(int i=1;i<=n;i++){for(int j=0;j<=m;j++){for(int k=0;k<3;k++){int k1,k2;if(k==0) k1=1,k2=2;else if(k==1) k1=0,k2=2;else k1=0,k2=1;if(k-a[i]==-1||(k==2&&a[i]==0))f[i][j][k]=max(max(f[i-1][j][k],f[i-1][j-1][k1]),f[i-1][j-1][k2])+1;else f[i][j][k]=max(max(f[i-1][j][k],f[i-1][j-1][k1]),f[i-1][j-1][k2]);}}}cout<<max(f[n][m][0],max(f[n][m][1],f[n][m][2]))<<endl;return ~~(0^_^0);
}

P1278 单词游戏

我们来想这道题的状态表示是啥

其实这里借鉴了状态压缩二进制的思想

就是二进制拼凑

f[i][j]表示在j状态下的当前数为i的max (我们还得知道当前数是谁是吧

爆搜咋做 ?

就是枚举每一个后面的可以接的单词 over

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
const int M = 1<<16;
//const int mod = 1e9+7;
#define int long long
#define LL long long
#define endl '\n'
#define Endl '\n'
#define _ 0
#define inf 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
int f[18][M],n;
string s[N];
vector<int>v[300];//首字母是是啥
int dfs(int x,int y){if(f[x][y])return f[x][y];int ans=0;for(auto i:v[s[x].back()]){if((y>>(i-1)&1)==0)ans=max(ans,dfs(i,y|(1<<(i-1))));}return f[x][y]=ans+s[x].size();
}
signed main(){fastcin>>n;for(int i=1;i<=n;i++){cin>>s[i];v[s[i][0]].push_back(i);}int ans=-2e9;for(int i=1;i<=n;i++)ans=max(ans,dfs(i,1<<(i-1)));cout<<ans<<endl;return ~~(0^_^0);
}

691. 立方体IV

我这道题第一遍不是记忆化搜索做的

就是很简单的找旁边有没有他爹

有的话标记为1

然后跑一遍连续的1 就可以了 O(1e6*100)

然后题解介绍了一种记忆化搜索的方法

我们首先想状态 

其实直接就是f[i] i这个点可以连多长了

我们爆搜 每一个点 要是旁边有他爹 就延续下去

这个时间复杂度是一样的

#include <bits/stdc++.h>
using namespace std;
const int N = 1e3+10;
const int M = 1e6+10;
const int mod = 1e9+7;
#define int long long
#define LL long long
#define endl '\n'
#define Endl '\n'
#define _ 0
#define inf 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
int w[N][N];
vector<pair<int,int>>v[M];
signed main(){fastint t;cin>>t;int tt=0;while(t--){tt++;int n;cin>>n;memset(w,0,sizeof w);memset(v,0,sizeof v);for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){cin>>w[i][j];v[w[i][j]].emplace_back(i,j);}}if(n==1){printf("Case #%d: 1 1\n",tt);continue;}int a[M]={0};for(int i=1;i<=n*n;i++){auto x=v[i].back().first,y=v[i].back().second;if(x-1>=1&&w[x-1][y]==i+1){a[i]=1;continue;}if(x+1<=n&&w[x+1][y]==i+1){a[i]=1;continue;}if(y-1>=1&&w[x][y-1]==i+1){a[i]=1;continue;}if(y+1<=n&&w[x][y+1]==i+1){a[i]=1;}}int ans=0,cnt=0,num;for(int i=1;i<=n*n;i++){if(a[i])cnt++;else cnt=0;if(cnt>ans){num=i;ans=cnt;}}while(a[num])num--;printf("Case #%d: %d %d\n",tt,num+1,ans+1);}return ~~(0^_^0);
}

记忆化搜索版

#include <bits/stdc++.h>
using namespace std;
const int N = 1e3+10;
const int M = 1e6+10;
const int mod = 1e9+7;
#define int long long
#define LL long long
#define endl '\n'
#define Endl '\n'
#define _ 0
#define inf 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
int w[N][N],n,f[M];
int dfs(int x,int y,int d){if(f[d])return f[d];int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};int ans=0;for(int i=0;i<4;i++){int x1=x+dx[i],y1=y+dy[i];if(w[x1][y1]==d+1){ans=dfs(x1,y1,d+1);break;}}return f[d]=ans+1;
}
signed main(){fastint t;cin>>t;for(int C=1;t;t--,C++){cin>>n;memset(w,0,sizeof w);memset(f,0,sizeof f);for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){cin>>w[i][j];}}int ans=0,id=0;for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){int res=dfs(i,j,w[i][j]);if(res>ans){ans=res,id=w[i][j];}else if(res==ans&&id>w[i][j]){id=w[i][j];}}}printf("Case #%d: %d %d\n",C,id,ans);}return ~~(0^_^0);
}

记忆化搜索 day48相关推荐

  1. 洛谷P1057 传球游戏(记忆化搜索)

    点我进入题目 题目大意:n个小孩围一圈传球,每个人可以给左边的人或右边的人传球,1号小孩开始,一共传m次,请问有多少种可能的路径使球回到1号小孩. 输入输出:输入n,m,输出路径的数量. 数据范围:4 ...

  2. 图论 ---- F. Graph Traveler 记忆化搜索 + 思维预处理(数论同余恒等式)

    题目链接 题目大意: q∈[1,1e5],n∈[1,1000],mi∈[1,10]q\in[1,1e5],n\in[1,1000],m_i\in[1,10]q∈[1,1e5],n∈[1,1000],m ...

  3. 思维dp ---- Codeforces Round #711 (Div. 2) - C. Planar Reflections[dp/记忆化搜索]

    题目链接 题目大意: 就是给你n个平面和一个寿命为k的衰变粒子.开始粒子从左向右飞行,粒子每经过一个平面就会产生一个副本粒子,这个副本粒子比原粒子的寿命少1,即为k-1,并且飞行方向是原粒子的反方向. ...

  4. Discovering Gold LightOJ - 1030[概率dp或者记忆化搜索]

    题目大意:有一个[1,n][1,n][1,n]的数轴,数轴上的每个对应位置上都有金矿,你初始位置是1,然后你每次都会投色子决定你下一步跳到哪里,如果你跳出了nnn,那么你就要重新投.问你跳到nnn的时 ...

  5. BZOJ 1589 Trick or Treat on the Farm (tarjan缩点,记忆化搜索)[Usaco 2008 Dec Gold]【BZOJ计划】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Weblink https://hydro.ac/d/bzoj/p/1589 Problem 每年万圣 ...

  6. UVA437 巴比伦塔 The Tower of Babylon(矩形嵌套进阶版、DAG上DP、记忆化搜索)

    整理的算法模板合集: ACM模板 本题和基础的矩形覆盖差不多,只不过变成了三维的长方形. 因为每次转移的时候只有顶面的x和y会影响决策的进行,所以我们只需要用一个二元组(a,b)(a, b)(a,b) ...

  7. [P1434 [SHOI2002]滑雪](DFS,记忆化搜索)

    P1434 [SHOI2002]滑雪 题目描述 Michael喜欢滑雪.这并不奇怪,因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你 ...

  8. hdu 4722(记忆化搜索)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4722 思路:简单的记忆化搜索,留意一下A==0时的情况就可以了. 1 #include<iost ...

  9. poj 1085 Triangle War 博弈论+记忆化搜索

    思路:总共有18条边,9个三角形. 极大极小化搜索+剪枝比较慢,所以用记忆化搜索!! 用state存放当前的加边后的状态,并判断是否构成三角形,找出最优解. 代码如下: 1 #include<i ...

最新文章

  1. python 读取excel文件 效率 时间 格式_python读取Excel文件中的时间数据
  2. 【手写系列】写一个迷你版的Tomcat
  3. 如何准备 Java 初级和高级的技术面试
  4. 当零售行业遇上小程序,该如何玩转全新商业模式
  5. Chrome历史版本查看
  6. Redis 过期策略+conf 记录
  7. 【IoT】5.Business Strategy 商业战略
  8. 中国人民大学与加拿大女王大学金融硕士——在这里,打开精彩“识界”
  9. 《OKR工作法》读书笔记
  10. register int 的作用
  11. softmax分类器 matlab,softmax原理及Matlab实现
  12. 旅游指南之五----途登山装备清单
  13. 达梦数据库(DM8)DCA培训及认证考试有感--附ODBC使用新场景
  14. iMeta | 华科宁康等打通中药成分鉴定和网络药理分析,助力中药标准化数字化国际化...
  15. 设计类笔记本计算机,适合设计师用的笔记本
  16. H5实现实时音频MP3上传至服务端
  17. [附源码]计算机毕业设计JAVA网上拍卖系统
  18. 电脑桌面右下角小人非常萌
  19. 双一流学科计算机科学与工程,“双一流”建设高校及建设学科名单
  20. 直播带货颜值到底重不重要,哪些人适合直播带货?丨国仁猫哥

热门文章

  1. CocosCreator像素鸟小游戏实现(有源码)超详细教程 TS实现小游戏 零基础开发
  2. 【java】javamail简介以及发送邮件
  3. 宽依赖和窄依赖_Spark --【宽依赖和窄依赖】
  4. 计算机科学导论第五版第二章答案,计算机科学导论样题1答案
  5. USB设备路径是什么,是什么格式的?
  6. 开放计算十年,西部数据的思考与探索
  7. JAVA网站视频播放不了_java视频播放网站小结
  8. 启动项目报错 Failed to bind properties under
  9. css网页网格线条背景
  10. 品悟C 抛弃C程序设计中的谬误与恶习 pdf