UVa 10599 - Robots(II)

传送门

UVa 10599 - Robots(II)

题意

一个机器人要打扫垃圾,只能左、下走,求他最多能扫几个垃圾,路线有几条,选择一条输出。

思路

$dp[i][j]$表示该点开始能打扫的最多垃圾。
然后记忆化搜索就行。

至于统计路线数目,也是用记忆化搜索,到最后一个垃圾时候返回1即可。

输出路线,只要满足某处有垃圾并且那点比当前点的垃圾数少1就行。

代码

#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int MAXN = 100 + 10;
const int INF = 2147483647;
 
int mp[MAXN][MAXN], dp[MAXN][MAXN], cnt, r, c, way[MAXN][MAXN];
 
int cal(int x, int y)
{
    int &cur = way[x][y];
    if (cur != -1)
        return cur;
    if (dp[x][y] == 1)
        return cur = 1;
    cur = 0;
    for (int i = x; i <= r; i++)
        for (int j = y; j <= c; j++)
            if (mp[i][j] && dp[i][j] + mp[x][y]== dp[x][y])
                cur += cal(i, j);
    return cur;
}
 
int DFS(int x, int y)
{
    int &cur = dp[x][y];
    if (cur != -1)
        return cur;
    if (x == r && y == c)
        return cur = mp[r][c];
    cur = 0;
    if (x + 1 <= r)
        cur = max(DFS(x + 1, y) + mp[x][y], cur);
    if (y + 1 <= c)
        cur = max(DFS(x, y + 1) + mp[x][y], cur);
    return cur;
}
 
void PrintAns(int x, int y)
{
    if (dp[x][y] == 1)
        if (mp[x][y])
        {
            printf(" %d\n", (x - 1) * c + y);
            return;
        }
    printf(" %d", (x - 1) * c + y);
    for (int i = x; i <= r; i++)
        for (int j = y; j <= c; j++)
            if (mp[i][j] && dp[x][y] - 1 == dp[i][j])
            {
                PrintAns(i, j);
                return;
            }
}
 
void OutPut()
{
    for (int i = 1; i <= r; i++)
        for (int j = 1; j <= c; j++)
            if (mp[i][j] && dp[i][j] == DFS(1, 1))
            {
                PrintAns(i, j);
                return;
            }
}
 
int main()
{
    //freopen("input.txt", "r", stdin);
    int i, j, a, b, cases = 0;
    while (scanf("%d%d", &r, &c), r + c != -2)
    {
        cnt = 0;
        memset(mp, 0, sizeof mp);
        memset(dp, -1, sizeof dp);
        memset(way, -1, sizeof way);
        while (scanf("%d%d", &a, &b), a + b)
            mp[a][b] = 1;
        int ans = DFS(1, 1);
        cal(1, 1);
        printf("CASE#%d: %d %d", ++cases, ans, way[1][1]);
        OutPut();
    }
    return 0;
}

Powered by Jekyll and Theme by solid