记忆化搜索专题
思想
记忆化搜索的思想无非就是:搜索 + DP
注意!!!
- 记忆化搜索要判断是从起点直接搜dfs(0,0)还是for循环遍历每一个点都要去搜!
- 判断是否需要标记book,还是book直接作为搜到已经搜过的直接返回的数组!
POJ1088-滑雪
注意:POJ上不能用万能头文件,把头文件注释掉之后用C++提交会无法提交(直接报错:error: bits/stdc++.h: No such file or directory,必须删除才可以。(为啥我也不晓得)
必须删除前几行注释掉的部分:
//#include<bits/stdc++.h>
//using namespace std;
//typedef long long ll;
AC代码:
#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#include<cmath>
#include<list>
#include<stdlib.h>
#include<map>
#include<stack>
#include<stdio.h>
#include<queue>
using namespace std;
typedef long long ll;
#define sc(T) scanf("%d",&T)
#define scc(x,y) scanf("%d %d",&x,&y)
#define pr(T) printf("%d\n",T)
#define f(a,b,c) for (int a=b;a<c;a++)
#define ff(a,b,c) for (int a=b;a>c;a--)
#define inf 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
#define eps 1e-9
#define PI acos(-1)
int a[110][110],n,m,ans,book[110][110];
int to[4][2]= {{0,1},{0,-1},{-1,0},{1,0}};
//void dfs(int x,int y,int cnt)
int dfs(int x,int y)
{
// if(cnt<=ans)
// return;
// ans=max(ans,cnt);
if(book[x][y])
return book[x][y];
//book[x][y]=1;
f(i,0,4)
{
int tx=x+to[i][0];
int ty=y+to[i][1];
// if(tx>=0&&tx<n&&ty>=0&&ty<m&&!book[tx][ty])
if(tx>=0&&tx<n&&ty>=0&&ty<m&&a[tx][ty]<a[x][y])
{
// book[tx][ty]++; // book[tx][ty]=1;
//book[tx][ty]=max(book[tx][ty],dfs(tx,ty));
book[x][y]=max(book[x][y],dfs(tx,ty)+1);
//book[tx][ty]--; // book[tx][ty]=0;
}
}
return book[x][y];
}
int main()
{
cin>>n>>m;
f(i,0,n)
{
f(j,0,m)
cin>>a[i][j];
}
// dfs(0,0,0);
ans=0; //小于等于0即可
f(i,0,n)
{
f(j,0,m)
ans=max(ans,dfs(i,j));
}
cout<<ans+1<<endl;
return 0;
}
HDU1078-FatMouse and Cheese
题意:自行百度。
AC代码:
//#include<bits/stdc++.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#include<cmath>
#include<list>
#include<stdlib.h>
#include<map>
#include<stack>
#include<stdio.h>
#include<queue>
using namespace std;
typedef long long ll;
#define sc(T) scanf("%d",&T)
#define scc(x,y) scanf("%d %d",&x,&y)
#define pr(T) printf("%d\n",T)
#define f(a,b,c) for (int a=b;a<c;a++)
#define ff(a,b,c) for (int a=b;a>c;a--)
#define inf 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
#define eps 1e-9
#define PI acos(-1)
int n,k,ans,a[110][110],book[110][110];
int to[4][2]= {{0,1},{0,-1},{-1,0},{1,0}};
int dfs(int x,int y)
{
if(book[x][y])
return book[x][y];
f(i,0,4)
{
f(j,0,k+1)
{
int tx=x+to[i][0]*j;
int ty=y+to[i][1]*j;
if(tx>=0&&tx<n&&ty>=0&&ty<n&&a[tx][ty]>a[x][y])
book[x][y]=max(book[x][y],dfs(tx,ty));
}
}
//return book[x][y];
return book[x][y]+=a[x][y];
}
int main()
{
while(~scc(n,k),n!=-1||k!=-1)
{
mem(book,0);
f(i,0,n)
{
f(j,0,n)
sc(a[i][j]);
}
int w=dfs(0,0);
//cout<<w<<endl;
cout<<book[0][0]<<endl;
}
return 0;
}
HDU1978-How many ways
记忆化搜索Ac代码:
//#include<bits/stdc++.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#include<cmath>
#include<list>
#include<stdlib.h>
#include<map>
#include<stack>
#include<stdio.h>
#include<queue>
using namespace std;
typedef long long ll;
#define sc(T) scanf("%d",&T)
#define scc(x,y) scanf("%d %d",&x,&y)
#define pr(T) printf("%d\n",T)
#define f(a,b,c) for (int a=b;a<c;a++)
#define ff(a,b,c) for (int a=b;a>c;a--)
#define inf 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
#define eps 1e-9
#define PI acos(-1)
#define mod 10000 //写1e4会报错 可以const int mod=1e4不会报错
int n,m,ans,a[110][110],book[110][110];
int to[2][2]= {{0,-1},{1,0}};
int dfs(int x,int y)
{
if(book[x][y]!=-1)
return book[x][y];
book[x][y]=0;
// if(x==n-1&&y==m-1)
// {
// ans++;
// return 0;
// }
// f(i,0,2)
// {
// int tx=x+to[i][0];
// int ty=y+to[i][0];
// if(tx>=0&&tx<n&&ty>=0&&ty<m)
// book[x][y]=(book[x][y]%mod+dfs(tx,ty)%mod)%mod;
//
// }
for(int i=0; i<=a[x][y]; i++)
{
for(int j=0; j<=a[x][y]-i; j++) //表示消耗那个格子的能量能到达的格子;
{
int tx=x+i;
int ty=y+j;
if(tx>=0&&tx<n&&ty>=0&&ty<m)
book[x][y]=(book[x][y]+dfs(x+i,y+j))%mod;
}
}
return book[x][y];
}
int main()
{
int T;
sc(T);
while(T--)
{
mem(book,-1);
ans=0;
scc(n,m);
f(i,0,n)
{
f(j,0,m)
sc(a[i][j]);
}
// f(i,0,n)
// {
// f(j,0,m)
// dfs(i,j);
// }
book[n-1][m-1]=1;
dfs(0,0);
cout<<book[0][0]%mod<<endl;
}
return 0;
}
这题也可以用DP写,
DP AC代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<string.h>
#include<queue>
#include<iostream>
#include<stack>
using namespace std;
typedef long long ll;
const int mod=1e4;
int a[110][110],dp[110][110];
int main()
{
int t,n,m;
cin>>t;
while(t--)
{
memset(dp,0,sizeof(dp));
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
}
dp[n][m]=1;
for(int i=n;i>=1;i--)
{
for(int j=m;j>=1;j--)
{
for(int p=0;p<=a[i][j]&&(i+p<=n);p++)
{
int ww=a[i][j]-p;
for(int q=0;q<=ww&&(j+q<=m);q++)
{
if(p==0&&q==0)
continue;
dp[i][j]=(dp[i][j]+dp[i+p][j+q])%mod;
}
}
}
}
int w=dp[1][1];
printf("%d\n",w);
}
return 0;
}