Lightoj1004(dp/记忆化dfs)易错!
来源:互联网 发布:雷欧奥特曼mac队介绍 编辑:程序博客网 时间:2024/06/11 06:04
题目:http://www.lightoj.com/volume_showproblem.php?problem=1004
题意:给定一个由数字组成的菱形,问从顶端走到底端的路线上数字的最大和,行走方式为可以从当前数字向下一层临近的两个数字走。
思路:动态规划。对于菱形的上半部,可以得状态转移方程为dp[i][j] += max(dp[i-1][j-1], dp[i-1][j]),对于下半部,可以得状态转移方程为dp[i][j] = max(dp[i-1][j], dp[i-1][j+1]),最后dp[2*n-1][1]就是答案
但是我非常想用dfs写!:
先来个错误代码:
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<sstream>using namespace std;int mp[210][210],num=0,n,vis[210][210];int nx[][2]= {1,0,1,1};int ny[][2]= {1,-1,1,0};int dfs(int x,int y){ int i,tx,ty; if(vis[x][y]!=0) return vis[x][y]; if(x==2*n-1) return mp[x][y]; if(x<=n-1) { for(i=0; i<2; i++) { tx=x+nx[i][0]; ty=y+nx[i][1]; if(mp[tx][ty]==0) continue; vis[tx][ty]=max(vis[tx][ty],dfs(tx,ty));//tx,ty会变,x,y这个点下方的左右两点根本没比较 } vis[x][y]=mp[x][y]+vis[tx][ty]; } else if(x>=n) { for(i=0; i<2; i++) { tx=x+ny[i][0]; ty=y+ny[i][1]; if(mp[tx][ty]==0) continue; vis[tx][ty]=max(vis[tx][ty],dfs(tx,ty)); } vis[x][y]=mp[x][y]+vis[tx][ty]; } return vis[x][y];}int main(){ int t,i,j,ss=1; cin>>t; while(t--) { num=0; memset(mp,0,sizeof(mp)); memset(vis,0,sizeof(vis)); scanf("%d",&n); for(i=1; i<=n; i++) for(j=1; j<=i; j++) scanf("%d",&mp[i][j]); for(i=n+1; i<=2*n-1; i++) for(j=1; j<=2*n-i; j++) scanf("%d",&mp[i][j]); num=dfs(1,1); printf("Case %d: %d\n",ss++,num); } return 0;}改正代码:
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<sstream>using namespace std;int mp[210][210],num=0,n,vis[210][210];int nx[][2]= {1,0,1,1};int ny[][2]= {1,-1,1,0};int dfs(int x,int y){ int tx,ty,i; if(vis[x][y]!=0) return vis[x][y]; if(x==2*n-1&&y==1) { return mp[x][y]; } if(x<=n-1) { for(i=0; i<2; i++) { tx=x+nx[i][0]; ty=y+nx[i][1]; if(mp[tx][ty]==0) continue; vis[x][y]=max(vis[x][y],mp[x][y]+dfs(tx,ty)); } } else if(x>=n) { for(i=0; i<2; i++) { tx=x+ny[i][0]; ty=y+ny[i][1]; if(mp[tx][ty]==0) continue; vis[x][y]=max(vis[x][y],mp[x][y]+dfs(tx,ty)); } } return vis[x][y];}int main(){ int t,i,j,ss=1; cin>>t; while(t--) { num=0; memset(mp,0,sizeof(mp)); memset(vis,0,sizeof(vis)); scanf("%d",&n); for(i=1; i<=n; i++) for(j=1; j<=i; j++) scanf("%d",&mp[i][j]); for(i=n+1; i<=2*n-1; i++) for(j=1; j<=2*n-i; j++) scanf("%d",&mp[i][j]); num=dfs(1,1); printf("Case %d: %d\n",ss++,num); } return 0;}
再来个超时代码:
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<sstream>using namespace std;int mp[210][210],num=0,n,vis[210][210];int nx[][2]= {1,0,1,1};int ny[][2]= {1,-1,1,0};int dfs(int x,int y){ if(x==2*n-1) return vis[x][y]=mp[x][y]; if(vis[x][y]>0) return vis[x][y]; if(x<n) return vis[x][y]=mp[x][y]+max(dfs(x+1,y),dfs(x+1,y+1)); else if(x<2*n-1&&x>=n) { if(y>1) return vis[x][y]=mp[x][y]+max(dfs(x+1,y),dfs(x+1,y-1));//会一直向下扩展,类似矩形剪去一个角,导致超时 else return vis[x][y]=mp[x][y]+dfs(x+1,y); }}int main(){ int t,i,j,ss=1; cin>>t; while(t--) { num=0; memset(mp,0,sizeof(mp)); memset(vis,0,sizeof(vis)); scanf("%d",&n); for(i=1; i<=n; i++) for(j=1; j<=i; j++) scanf("%d",&mp[i][j]); for(i=n+1; i<=2*n-1; i++) for(j=1; j<=2*n-i; j++) scanf("%d",&mp[i][j]); num=dfs(1,1); printf("Case %d: %d\n",ss++,num); } return 0;}
改正代码:
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<sstream>using namespace std;int mp[210][210],num=0,n,vis[210][210];int nx[][2]= {1,0,1,1};int ny[][2]= {1,-1,1,0};int dfs(int x,int y){ if(x==2*n-1) return vis[x][y]=mp[x][y]; if(vis[x][y]>0) return vis[x][y]; if(x<n) return vis[x][y]=mp[x][y]+max(dfs(x+1,y),dfs(x+1,y+1)); else if(x<2*n-1&&x>=n) { if(y==1) return vis[x][y]=mp[x][y]+dfs(x+1,y); else if(y==2*n-x) return vis[x][y]=mp[x][y]+dfs(x+1,y-1); else return vis[x][y]=mp[x][y]+max(dfs(x+1,y),dfs(x+1,y-1)); }}int main(){ int t,i,j,ss=1; cin>>t; while(t--) { num=0; memset(mp,0,sizeof(mp)); memset(vis,0,sizeof(vis)); scanf("%d",&n); for(i=1; i<=n; i++) for(j=1; j<=i; j++) scanf("%d",&mp[i][j]); for(i=n+1; i<=2*n-1; i++) for(j=1; j<=2*n-i; j++) scanf("%d",&mp[i][j]); num=dfs(1,1); printf("Case %d: %d\n",ss++,num); } return 0;}
学习就是不断纠错的过程,加油!
阅读全文
0 0
- Lightoj1004(dp/记忆化dfs)易错!
- HDU1078 记忆化DFS+dp
- lightoj1004【基础DP】
- hdu1208Pascal's Travels (DFS+记忆化搜索(DP))
- poj 1088 dp记忆化搜索状态( or dfs)
- 历届试题 地宫取宝 (DP+记忆化DFS)
- hdu5456 Matches Puzzle Game(记忆化dfs+dp)
- HDU - 3652 HDU - 3652 (数位DP&记忆化dfs)
- HDU - 4734 F(x) (数位DP&记忆化dfs)
- HDU-3709-Balanced Number(数位DP+记忆化DFS)
- 记忆化搜索 dp(dfs)-帮助Jimmy POJ--1661
- FatMouse and Cheese (DFS + DP 记忆化搜索)
- poj 1088 滑雪 DP(dfs的记忆化搜索)
- HDU1978How Many Ways 记忆化dfs+dp
- poj 1088 滑雪(DP+记忆化dfs)
- cache式DP(记忆化dfs)
- hdu3555 Bomb 【数位dp+记忆化dfs】
- HDU1078:记忆搜索(dp+dfs)
- Android Https相关完全解析 当OkHttp遇到Https
- c++ s.c_str()用法
- 如何在c语言中源文件调用另一个源文件的函数
- 关于泛型 java
- 嵌入式Linux系统移植的四大步骤
- Lightoj1004(dp/记忆化dfs)易错!
- Codeforces Round #249 (Div. 2 Only)(A-E)
- placement new的用法
- tomcat源码中用到的设计模式
- KMP算法求next数组的一些理解
- Dubbo各种协议
- java中byte类型数据的运算
- Haut 1282: ykc想吃好吃的(最大连续子段和,首尾相连)
- 策略模式 | Strategy Pattern