//
// main.cpp
// uva 10599 - Robots(II) --动态规划
/*
此题的状态转移方程好想,很简单。
d[i][j] = max(d[i+1][j] ,d[i][j+1]) + g[i][j] ;
另外 求其中的一条路径也好写。
对于方案数,这是难点啊。MD,原来 即使行代码就解决的,价格方案数。。。。。
这里方案数,要注意的是注意重复,不能根据上面的地推方程来想。对于i行j列,如果(i+1,j) ,((i,j+1)都不存在垃圾,(i+1,j+1)存在垃圾,那么我们按照count[i][j] = count[i+1][j] +count[i][j+1],就会重复的加上了count[i+1][j+1].
从g[i][j]出发 ,count[i][j] = sum(count[x][y]) ,其中d[x][y] + g[i][j] = d[i][j].如果 (i,j)是最后一个垃圾, count[i][j] =1 (这是我wa的原因);这个地推方程也是很容易想到的。
但是如何找到下一个垃圾点呢?这个垃圾点得满足 从
(i, j ) 到(x,y)存在一条不包含垃圾的路径.这显然可以使用bfs就解决了。
到这里这道题就可以AC了。
*/
#include <iostream>
#include <queue>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<vector>
#include <string.h>
#include <algorithm>
#include <set>
#include <map>
#include <cstdio>
#define ll long long
using namespace std ;
int d[110][110] ;
int g[110][110] ;
ll ways[110][110] ;
int n , m ;
vector<int > path ;
struct node{
int x ,y ;
node(int x , int y ):x(x) ,y(y){} ;
};
vector<node > touch[110][110] ;
int flag[110][110];
int dir[2][2] ={{0 , 1},{1,0}} ;
void bfs(int x,int y )
{
memset(flag, 0, sizeof(flag)) ;
touch[x][y].clear() ;
queue<node> q ;
int tx = x, ty = y ;
q.push(node(x , y )) ;
flag[x ][y] = 1 ;
while (!q.empty()) {
node u = q.front() ; q.pop() ;
// x = u.x ; y = u .y ;
for (int i = 0; i < 2; i++) {
x = u.x + dir[i][0 ] ; y = u.y + dir[i][1] ;
if(x <= n &&y <= m && !flag[x][y])
{
flag[x][y] =1 ;
if(g[x][y]){
touch[tx][ty].push_back(node(x,y) ) ;
//
// bfs(x, y) ;
continue ;
}
else{
q.push(node(x,y)) ;
}
}
}
}
}
ll getWays(int x , int y)
{
if (ways[x][y] >=0) {
return ways[x][y] ;
}
if(x == n || y == m )
{
return ways[x][ y] = 1 ;
}
else{
ll ans = 0 ;
bfs(x, y) ;
int len = (int )touch[x][y].size() ;
for (int i = 0 ; i < len ; i++) {
int x1 = touch[x][y][i].x ;
int y1 = touch[x][y][i].y ;
if(d[x][y] == g[x][y] + d[x1][y1])
{
ans += getWays(x1, y1) ;
}
}
if (ans == 0 ) {
ans = 1 ;
}
ways[x][y] = ans ;
return ans ;
}
}
void getPath(int x , int y)
{
if (g[x][y] == 1 ) {
path.push_back(x*m - m + y) ;
}
if (y<m && d[x][y] == g[x][y] + d[x][y+1]) {
getPath(x, y+1) ;
}
else if(x < n &&d[x][y] == g[x][y] + d[x+1][y])
{
getPath(x+1, y) ;
}
}
int main() {
int x,y,kase=0;
while (scanf("%d %d" ,&n,&m)==2 && n + m !=-2 ) {
memset(g, 0, sizeof(g)) ;
while (scanf("%d %d" ,&x,&y)==2&& x!= 0 && y!= 0 ) {
g[x][y] = 1 ;
}
memset(d, 0, sizeof(d)) ;
for (int i = m; i>0; i--) {
d[n][i] = d[n][i+1] +g[n][i] ;
}
for (int i = n-1; i>0; i--) {
d[i][m] = d[i+1][m] + g[i][m] ;
for (int j = m-1 ; j>0; j--) {
d[i][j] = g[i][j] ;
d[i][j] += max(d[i][j+1] , d[i+1][j]) ;
}
}
printf("CASE#%d: %d" , ++kase,d[1][1]) ;
memset(ways, -1, sizeof(ways)) ;
printf(" %lld" , getWays(1, 1)) ;
path.clear() ;
getPath(1,1) ;
for (int i = 0 ; i < path.size(); i++) {
printf(" %d" ,path[i]) ;
}
cout << endl;
}
return 0;
}
uva 10599 - Robots(II) -动态规划
最新推荐文章于 2017-12-02 12:42:58 发布