记忆化搜索(13)

记忆化搜索

连续补了几天的DFS+BFS,整个人都不好了。。。
今天给大家简绍一些简单的东西——记忆化搜索,听起来虽然很高大上,但是的确挺好用,嘿嘿!!!(放心,这次没有那么难)怎么说呢,这个是真的不难,就是把算好的结果用一个数组存起来。直接上题吧!(不要问板子,这个内容已经水到没板子了)

传送门:Function Run Fun POJ - 1579

读完题直接写就ok了…先感受一下这个记忆化搜索…就是把算好的结果存起来…

#include<iostream>
#include<stdio.h>
#include<cstring>
using namespace std;
int dp[100][100][100];
int w(int a,int b,int c)
{
	if(a<=0||b<=0||c<=0)
		return 1;
	if(a>20||b>20||c>20)
		return w(20,20,20);
	if(dp[a][b][c])
		return dp[a][b][c];
	if(a<b&&b<c)
		return dp[a][b][c]=w(a,b,c-1)+w(a,b-1,c-1)-w(a,b-1,c);
	else
		return dp[a][b][c]=w(a-1,b,c)+w(a-1,b-1,c)+w(a-1,b,c-1)-w(a-1, b-1, c-1); 
}
int main()
{
	int a,b,c;
	while(~scanf("%d %d %d",&a,&b,&c)&&a!=-1||b!=-1||c!=-1)
	{
		memset(dp,0,sizeof dp);
		int tt=w(a,b,c);
		printf("w(%d, %d, %d) = %d\n",a,b,c,tt);
	}
	return 0;
}

传送门:滑雪 POJ - 1088

熟悉的DFS,就是加了一个记忆化数组,水水水起来…

#include<iostream>
#include<stdio.h>
#include<cstring>
//#include<bits/stdc++.h>
using namespace std;
int dp[110][110];
int mp[110][110];
int n,m;
int dd[4][2]={-1,0,1,0,0,1,0,-1};
int dfs(int x,int y)
{
	if(dp[x][y])
		return dp[x][y];
	int maxlen=1;
	int len;
	for(int i=0;i<4;i++)
	{
		int dx=x+dd[i][0];
		int dy=y+dd[i][1];
		if(dx>=0&&dy>=0&&dx<n&&dy<m&&mp[dx][dy]<mp[x][y])
		{
			len=dfs(dx,dy)+1;
			maxlen=max(len,maxlen);
		}
	}
	return dp[x][y]=maxlen;
}

int main()
{
	
	while(~scanf("%d%d",&n,&m))
	{
		memset(dp,0,sizeof dp);
		memset(mp,0,sizeof mp);
		for(int i=0;i<n;i++)
			for(int j=0;j<m;j++)
				cin>>mp[i][j];
		int cnt=0;
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				int tt=dfs(i,j);
				cnt=max(tt,cnt);
			}
		}
		cout<<cnt<<endl;
	}
	return 0;
}

传送门: FatMouse and Cheese HDU - 1078

#include<iostream>
#include<stdio.h>
#include<cstring>
using namespace std;
int n,m,step;
int a[110][110];
int dp[110][110];
int dd[4][2]={-1,0,1,0,0,1,0,-1};
int dfs(int x,int y)
{
	
	if(dp[x][y])
		return dp[x][y];
	int ans=0;
	for(int i=0;i<4;i++)	                                                                                                                                                                                                                    
	{
		for(int j=1;j<=m;j++)
		{
			int dx=x+dd[i][0]*j;
			int dy=y+dd[i][1]*j;
			if(dx>=0&&dy>=0&&dx<n&&dy<n&&a[dx][dy]>a[x][y])
			{
				int tmp=dfs(dx,dy);
				if(ans<tmp)
					ans=tmp;
			}
		}
	}
	dp[x][y]=ans+a[x][y];
	return dp[x][y];
}
int main()
{      
	while(~scanf("%d%d",&n,&m)&&n!=-1||m!=-1)
	{
		memset(dp,0,sizeof dp);
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				cin>>a[i][j];
		dfs(0,0);	
		cout<<dp[0][0]<<endl;
	}
	return 0;
}

传送门:Bone Collector HDU - 2602

这是个背包问题,先看看吧!以后会详细简绍背包问题。

#include<iostream>
#include<stdio.h>
#include<cstring>
using namespace std;
int w[1000]; //保存物品的重量
int v[1000]; //保存物品的价值
int dp[1000][1000]; //记忆化数组,要初始化为-1
int n,vv; //n个物品
// 从第i个物品开始挑选总重量小于j的部分
int dfs(int i,int j)
{
	if(dp[i][j] >= 0) 
		return dp[i][j]; //已经计算过的话直接使用之前的结果
	int res;
	if(i == n) 
		res = 0; //已经没有物品
	else if (j < w[i]) 
		res = dfs(i + 1,j); //无法挑选
	else 
		res = max(dfs(i + 1, j), dfs(i + 1,j - w[i]) + v[i]); //挑选和不挑选两种情况都尝试一下
	return dp[i][j] = res; //保存结果并返回
}
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		memset(dp,-1,sizeof dp);
		cin>>n>>vv;
		for(int i=0;i<n;i++)
			cin>>v[i];
		for(int j=0;j<n;j++)
			cin>>w[j];
		int ff=dfs(0,vv);
		cout<<ff<<endl; 
	}
	return 0;
}

传送门:漫步校园 HDU - 1428

给大家一个CV代码,这个我没做出来…

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
struct node
{
    int x,y,c;
    bool friend operator <(node a,node b)
    {
        return a.c>b.c;
    }
}r,w;
ll ma[305][305],vis[305][305],dis[305][305],dp[305][305];
int d[4][2]={0,1,1,0,-1,0,0,-1};
void bfs()
{
    priority_queue<node> q;
    r.x=n-1,r.y=n-1;r.c=ma[n-1][n-1];
    dis[n-1][n-1]=ma[n-1][n-1];
    vis[n-1][n-1]=1;
    q.push(r);
    while(!q.empty())
    {
        r=q.top();
        q.pop();
        for(int i=0;i<4;i++)
        {
            int dx=r.x+d[i][0];
            int dy=r.y+d[i][1];
            if(dx<0||dy<0||dx>=n||dy>=n||vis[dx][dy])    
				continue;
            w.x=dx,w.y=dy,w.c=r.c+ma[dx][dy];
            vis[dx][dy]=1;
            q.push(w);
            dis[dx][dy]=w.c;
        }
    }
}
ll dfs(ll x,ll y)
{
    if(x==n-1&&y==n-1)    return 1;
    if(dp[x][y]!=-1)    return dp[x][y];
    dp[x][y]=0;
    for(int i=0;i<4;i++)
    {
        int dx=x+d[i][0];
        int dy=y+d[i][1];
        if(dx<0||dy<0||dx>=n||dy>=n||dis[dx][dy]>=dis[x][y])    continue;
        dp[x][y]+=dfs(dx,dy);
    }
    return dp[x][y];
}
int main()
{
    while(cin>>n)
    {
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                cin>>ma[i][j];
        memset(vis,0,sizeof(vis));
        memset(dp,-1,sizeof(dp));
        bfs();
        cout<<dfs(0,0)<<endl;
    }
}
发布了41 篇原创文章 · 获赞 5 · 访问量 2276

猜你喜欢

转载自blog.csdn.net/mumuhaoshuai/article/details/100942710