hdu 1078+hdu1978+hdu 1428

来源:互联网 发布:诺基亚lumia800软件 编辑:程序博客网 时间:2024/06/03 14:52

贴几道记忆化搜索的题。。。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1078

View Code
 1 #include<iostream> 2 const int MAXN=110; 3 using namespace std; 4 int dp[MAXN][MAXN]; 5 int map[MAXN][MAXN]; 6 int n,m; 7 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; 8  9 int dfs(int x,int y){10     if(dp[x][y])return dp[x][y];11     int MAX=0;12     for(int i=0;i<4;i++){13         //一个方向上每次最多走m步;14         for(int j=1;j<=m;j++){15             int xx=x+dir[i][0]*j;16             int yy=y+dir[i][1]*j;17             if(xx>=1&&xx<=n&&yy>=1&&yy<=n&&map[xx][yy]>map[x][y]){18                 MAX=max(MAX,dfs(xx,yy));//保存当前路的最大值19                 //printf("%d\n",MAX);20             }21         }22     }23     dp[x][y]=MAX+map[x][y];24     return dp[x][y];25 }26 27 28 int main(){29     while(~scanf("%d%d",&n,&m)){30         if(n==-1&&m==-1)break;31         for(int i=1;i<=n;i++){32             for(int j=1;j<=n;j++){33                 scanf("%d",&map[i][j]);34             }35         }36         memset(dp,0,sizeof(dp));37         int ans=dfs(1,1);38         printf("%d\n",ans);39     }40     return 0;41 }

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1978

View Code
 1 #include<iostream> 2 const int MAXN=110; 3 const int MOD=10000; 4 using namespace std; 5 int map[MAXN][MAXN]; 6 int dp[MAXN][MAXN]; 7 int n,m; 8  9 int dfs(int x,int y){10     if(x==n&&y==m){11         return 1;12     }13     if(dp[x][y])return dp[x][y];14     int ans=0;15     for(int i=0;i<=map[x][y];i++){16         for(int j=0;j+i<=map[x][y];j++){17             if(!(i==0&&j==0)&&x+i<=n&&y+j<=m){18                 dp[x][y]+=dfs(x+i,y+j);19                 dp[x][y]%=MOD;20             }21         }22     }23     return dp[x][y];24 }25 26 int main(){27     int _case;28     scanf("%d",&_case);29     while(_case--){30         scanf("%d%d",&n,&m);31         for(int i=1;i<=n;i++){32             for(int j=1;j<=m;j++){33                 scanf("%d",&map[i][j]);34             }35         }36         memset(dp,0,sizeof(dp));37         int ans=(dfs(1,1))%MOD;38         printf("%d\n",ans);39     }40     return 0;41 }

 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1428

注:他考虑从A区域到B区域仅当存在一条从B到机房的路线比任何一条从A到机房的路线更近(否则可能永远都到不了机房了…”这句话一定要理解清楚。就是说,对于当前位置,如果下一个状态与终点的最短距离大于或者等于当前位置到终点的最短距离,那么这个下一个状态是不可取的!到此,就能明白,此题就是求出所有点与终点的最短距离,然后再从起点进行记忆化搜索。

bfs求机房到各点的最短距离,dfs进行记忆化搜索

View Code
 1 #include<iostream> 2 #include<queue> 3 const int MAXN=55; 4 const int inf=1<<30; 5  6 using namespace std; 7 int n; 8 int map[MAXN][MAXN]; 9 bool visited[MAXN];10 int dist[MAXN][MAXN];11 __int64 dp[MAXN][MAXN];12 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};13 struct Node{14     int x,y;15 };16 17 //求机房到各点的距离18 void BFS(){19     queue<Node>Q;20     Node p,q;21     p.x=n,p.y=n;22     dist[n][n]=map[n][n];23     Q.push(p);24     while(!Q.empty()){25         p=Q.front();26         Q.pop();27         for(int i=0;i<4;i++){28             q.x=p.x+dir[i][0];29             q.y=p.y+dir[i][1];30             if(q.x>=1&&q.x<=n&&q.y>=1&&q.y<=n){31                 if(map[q.x][q.y]+dist[p.x][p.y]<dist[q.x][q.y]){32                     dist[q.x][q.y]=dist[p.x][p.y]+map[q.x][q.y];33                     Q.push(q);34                 }35             }36         }37     }38 }39 40 //从(1,1)开始记忆化搜索41 __int64 dfs(int x,int y){42     if(x==n&&y==n){43         return 1;44     }45     if(dp[x][y])return dp[x][y];46     for(int i=0;i<4;i++){47         int xx=x+dir[i][0];48         int yy=y+dir[i][1];49         if(xx>=1&&xx<=n&&yy>=1&&yy<=n&&dist[xx][yy]<dist[x][y]){50             dp[x][y]+=dfs(xx,yy);51         }52     }53     return dp[x][y];54 }55 56 57 int main(){58     while(~scanf("%d",&n)){59         for(int i=1;i<=n;i++){60             for(int j=1;j<=n;j++){61                 dist[i][j]=inf;62                 scanf("%d",&map[i][j]);63             }64         }65         BFS();66         memset(dp,0,sizeof(dp));67         __int64 ans=dfs(1,1);68         printf("%I64d\n",ans);69     }70     return 0;71 }

 

0 0