zoukankan      html  css  js  c++  java
  • 矩阵类型DP

    1、滑雪:从每个点开始枚举,记忆化搜索,记录dp[x][y]

    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<stack>
    #include<cstdio>
    #include<queue>
    #include<map>
    #include<vector>
    #include<set>
    using namespace std;
    const int maxn=1010;
    const int INF=0x3fffffff;
    int h[110][100];
    int dp[110][110];
    int r,c;
    int dis[4][2]={{0,1},{0,-1},{-1,0},{1,0}};
    int solve(int x,int y){
    	if(x<1||x>r||y<1||y>c) return 0;
    	if(dp[x][y]!=0) return dp[x][y];
    	dp[x][y]=1; //本身的高度别忘了 
    	for(int i=0;i<4;i++){
    		int xx=x+dis[i][0],yy=y+dis[i][1];
    		if(h[xx][yy]>h[x][y]) dp[x][y]=max(dp[x][y],solve(xx,yy)+1);
    }
    	return dp[x][y];
    }
    int main(){
    	scanf("%d %d",&r,&c);
    	for(int i=1;i<=r;i++)
    	for(int j=1;j<=c;j++) scanf("%d",&h[i][j]);
    	int ans=0;
    	for(int i=1;i<=r;i++)
    	for(int j=1;j<=c;j++) {
    		ans=max(ans,solve(i,j));
    	}
    	printf("%d",ans);
    return 0;
    }  

    2、传纸条

    4维----3维

    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<stack>
    #include<cstdio>
    #include<queue>
    #include<map>
    #include<vector>
    #include<set>
    using namespace std;
    const int maxn=1010;
    const int INF=0x3fffffff;
    int a[51][51];
    int f[110][51][51]; //第一位要扩大1倍 
    int n,m; 
    /*
    第二种做法为三维dp,如果这道题数据被加强了一点,那就应该用这个方法。
    仔细观察,我们不难发现一个规律,对于每次转移,这两位同学的纸条走的步数总是相等的,也就是应该总有i+j = k+l = step,我们从这里考虑入手,简化一下那个方程。
    我们枚举走的步数,同时枚举第一个人和第二个人的横坐标或者纵坐标,对,只枚举一个就好,另一个可以算出来。
    我枚举的是横坐标。
    但这样做第一维(也就是枚举步数那一维)要开两倍大小(步数最大有n+m-1),并且需要加入判断重合操作。
    优化之后速度比上一个快很多,它的时间复杂度是O(n^2*(n+m)).
    */
    int main(){
    	scanf("%d %d",&n,&m);
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=m;j++) scanf("%d",&a[i][j]);
    	}
    	for(int step=1;step<n+m;step++){
    		for(int i=1;i<=n;i++){
    			for(int x=1;x<=n;x++){
    				int j=step-i+1;
    				int y=step-x+1;
    				if(j<1||y<1) continue;
    				f[step][i][x]=max(max(f[step-1][i-1][x-1],f[step-1][i][x]),max(f[step-1][i-1][x],f[step-1][i][x-1]))+a[i][j]+a[x][y];
    				if(i==x) f[step][i][x]-=a[i][j];
    			}
    		}
    	}
    	printf("%d
    ",f[n+m-1][n][n]);
    return 0;
    }
    

      

  • 相关阅读:
    DataGridView 移动行
    DataGridView 显示提示信息
    模块和类的区别
    C# 流总结
    很口语I'm on my way
    读书笔记_Effective_C++_条款二十三:宁以nonmember、nonfriend替换member函数
    PDB文件:每个开发人员都必须知道的
    qq农场,数据抓包分析,实现源码,图片讲解
    连连看外挂消去算法分析
    关于“服务器提交了协议冲突. Section=ResponseStatusLine"问题请
  • 原文地址:https://www.cnblogs.com/shirlybaby/p/12296301.html
Copyright © 2011-2022 走看看