MemoryGarden's Blog

努力 -----------大能猫

C++博客 首页 新随笔 联系 聚合 管理
  118 Posts :: 11 Stories :: 20 Comments :: 0 Trackbacks
链接 :http://acm.pku.edu.cn/JudgeOnline/problem?id=2704


人生第一个dp,出现在了  2008-09-06 01:00:56 ,铭记这一时刻。(只能说我是菜鸟......but happy)


题意 :有一个小球,在矩阵上滚动,每次只能向右或者向下滚动,滚动的长度点是矩阵相应位置的数字,停止在滚动后的位置,不能滚动出图外面,0代表死胡同。问能停止在右下角的路径有多少条。

输入 :

4           //矩阵范围
2331        //矩阵
1213
1231
3110






想法 :开始想到bfs,交过,tle,但是后来想感觉即使不超时也不对,因为一个点有可能走过多次。是我自己的想法。后来越看越像dp了,最后
的目标点,到他的路径,是它左边的能走到它的点,和右边能走到它的点的路径的和,那么,这样推上去,就可以划分出它的子问题。(汗,这样写
大家不要笑话,因为我没有看过算法导论上的dp),因该是属于递推吧。再从上往下,一直推到目标点。就可以了。

只能向右 :横坐标单调递增

只能向下 :纵坐标单调递增

因为起点的能第一次达到的点的路径个数一定是1,所以最后存储结果的res[0][0] = 1;


核心代码 :

1. 因为横纵都是单调递增的,所以横向检测图中从点(small, column)到点(big, column)有没有0值的点,直接枚举每个位置,且不包含
两个端点

1 bool rok(int s, int b, int c){
2     int i;
3     for(i = s + 1; i < b; i++)
4         if(!map[i][c])return false;
5     return true;
6 }




2.因为横纵都是单调递增的,所以横向检测图中从点(row, small)到点(row, big)有没有0值的点,直接枚举每个位置,且不包含
两个端点

1 bool cok(int s, int b, int r){
2     int i, j;
3     for(i = s + 1; i < b; i++)
4         if(!map[r][i])return false;
5     return true;
6 }




3.递推的过程,从前往后,进行递推,如果不是只能向右或者向下,是不满足递推的条件的,不是单调的(不知道这里理解的对不对)


 1         res[0][0= 1//起始点的第一个到达的点的路径个数一定是1。
 2         for(i = 0; i < n; i++){
 3             for(j = 0; j < n; j++){
 4                 if(res[i][j] && i != n - 1 || j != n - 1){ //可达,而且不是右下角的点
 5                     //向右                
 6                     if(i + map[i][j] < n && rok(i, i + map[i][j], j)) //若在图内,且从起点到滚动停止点,图中没有0值点
 7                         res[i + map[i][j]][j] += res[i][j]; //滚动停止点的路径条数 = 起始点的路径条数 + 停止点的路径条数
 8                     //向下
 9                     if(j + map[i][j] < n && cok(j, j + map[i][j], i))
10                         res[i][j + map[i][j]] += res[i][j];
11                 }
12             }
13         }



ps : 题目提示c或者c++要用long long存储结果,可是"%ld"输出wa了n次,后来看了discuss后改的"%I64d"输出后ac

     
1 printf("%I64d\n", res[n - 1][n - 1]);



posted on 2008-09-06 01:48 memorygarden 阅读(672) 评论(1)  编辑 收藏 引用 所属分类: 报告

Feedback

# re: poj 2704 Pascal's Travels 2011-02-15 19:54 acmer
感谢你的ps:。。。
改成I64d果然也ac了  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理