solution.md 6.2 KB
Newer Older
每日一练社区's avatar
每日一练社区 已提交
1
# 地宫取宝
F
fix bug  
feilong 已提交
2

每日一练社区's avatar
每日一练社区 已提交
3
X 国王有一个地宫宝库,是 n×m 个格子的矩阵,每个格子放一件宝贝,每个宝贝贴着价值标签。
每日一练社区's avatar
每日一练社区 已提交
4

每日一练社区's avatar
每日一练社区 已提交
5
地宫的入口在左上角,出口在右下角。
每日一练社区's avatar
每日一练社区 已提交
6

每日一练社区's avatar
每日一练社区 已提交
7
小明被带到地宫的入口,国王要求他只能向右或向下行走。
每日一练社区's avatar
每日一练社区 已提交
8

每日一练社区's avatar
每日一练社区 已提交
9
走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。
每日一练社区's avatar
每日一练社区 已提交
10

每日一练社区's avatar
每日一练社区 已提交
11
当小明走到出口时,如果他手中的宝贝恰好是 k 件,则这些宝贝就可以送给小明。
每日一练社区's avatar
每日一练社区 已提交
12

每日一练社区's avatar
每日一练社区 已提交
13 14
请你帮小明算一算,在给定的局面下,他有多少种不同的行动方案能获得这 k 件宝贝。

15
**输入格式**
F
fix bug  
feilong 已提交
16

每日一练社区's avatar
每日一练社区 已提交
17
第一行 3 个整数,n,m,k,含义见题目描述。
每日一练社区's avatar
每日一练社区 已提交
18

每日一练社区's avatar
每日一练社区 已提交
19 20
接下来 n 行,每行有 m 个整数 Ci 用来描述宝库矩阵每个格子的宝贝价值。

21
**输出格式**
F
fix bug  
feilong 已提交
22

每日一练社区's avatar
每日一练社区 已提交
23
输出一个整数,表示正好取 k 个宝贝的行动方案数。
每日一练社区's avatar
每日一练社区 已提交
24

每日一练社区's avatar
每日一练社区 已提交
25 26
该数字可能很大,输出它对 1000000007 取模的结果。

27
**数据范围**
F
fix bug  
feilong 已提交
28

每日一练社区's avatar
每日一练社区 已提交
29 30 31 32 33
```
1≤n,m≤50,
1≤k≤12,
0≤Ci≤12
```
每日一练社区's avatar
每日一练社区 已提交
34

35
**输入样例1:**
F
fix bug  
feilong 已提交
36

每日一练社区's avatar
每日一练社区 已提交
37 38 39 40 41
```
2 2 2
1 2
2 1
```
每日一练社区's avatar
每日一练社区 已提交
42

43
**输出样例1:**
F
fix bug  
feilong 已提交
44

每日一练社区's avatar
每日一练社区 已提交
45 46 47
```
2
```
每日一练社区's avatar
每日一练社区 已提交
48

49
**输入样例2:**
F
fix bug  
feilong 已提交
50

每日一练社区's avatar
每日一练社区 已提交
51 52 53 54 55
```
2 3 2
1 2 3
2 1 5
```
每日一练社区's avatar
每日一练社区 已提交
56

57
**输出样例2:**
F
fix bug  
feilong 已提交
58

每日一练社区's avatar
每日一练社区 已提交
59 60 61 62
```
14
```

每日一练社区's avatar
每日一练社区 已提交
63
以下选项<span style="color:red">错误</span>的是?
每日一练社区's avatar
每日一练社区 已提交
64

每日一练社区's avatar
每日一练社区 已提交
65
## aop
F
fix bug  
feilong 已提交
66

每日一练社区's avatar
每日一练社区 已提交
67
### before
F
fix bug  
feilong 已提交
68

每日一练社区's avatar
每日一练社区 已提交
69
```c
每日一练社区's avatar
每日一练社区 已提交
70
#include <bits/stdc++.h>
每日一练社区's avatar
每日一练社区 已提交
71 72
using namespace std;
```
每日一练社区's avatar
每日一练社区 已提交
73

每日一练社区's avatar
每日一练社区 已提交
74
### after
F
fix bug  
feilong 已提交
75

每日一练社区's avatar
每日一练社区 已提交
76
```c
每日一练社区's avatar
每日一练社区 已提交
77 78 79 80

```

## 答案
F
fix bug  
feilong 已提交
81

每日一练社区's avatar
每日一练社区 已提交
82
```c
每日一练社区's avatar
每日一练社区 已提交
83 84 85 86 87 88 89 90
const int N = 55, M = 15, mod = 1e9 + 7;

int w[N][N];
int memo[N][N][M][M];

int n, m, K, ans;

int dfs(int i, int j, int k, int c)
每日一练社区's avatar
每日一练社区 已提交
91
{
每日一练社区's avatar
每日一练社区 已提交
92 93 94
    if (memo[i][j][k][c] != -1)
        return memo[i][j][k][c];
    if (i == n && j == m)
每日一练社区's avatar
每日一练社区 已提交
95
    {
每日一练社区's avatar
每日一练社区 已提交
96 97 98 99
        if (k == K || (k == K - 1 && w[i][j] > c))
            return 1;
        else
            return 0;
每日一练社区's avatar
每日一练社区 已提交
100
    }
每日一练社区's avatar
每日一练社区 已提交
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
    int sum = 0;
    if (i + 1 <= n)
    {
        if (w[i][j] > c)
            sum = (sum + dfs(i + 1, j, k + 1, w[i][j])) % mod;
        sum = (sum + dfs(i + 1, j, k, c)) % mod;
    }
    if (j + 1 <= m)
    {
        if (w[i][j] > c)
            sum = (sum + dfs(i, j + 1, k + 1, w[i][j])) % mod;
        sum = (sum + dfs(i, j, k, c)) % mod;
    }
    return memo[i][j][k][c] = sum % mod;
}

int main()
{
    scanf("%d %d %d", &n, &m, &K);
每日一练社区's avatar
每日一练社区 已提交
120 121 122 123
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
每日一练社区's avatar
每日一练社区 已提交
124 125
            scanf("%d", &w[i][j]);
            w[i][j]++;
每日一练社区's avatar
每日一练社区 已提交
126 127
        }
    }
每日一练社区's avatar
每日一练社区 已提交
128 129 130
    memset(memo, -1, sizeof(memo));
    dfs(1, 1, 0, 0);
    printf("%d\n", memo[1][1][0][0]);
每日一练社区's avatar
每日一练社区 已提交
131 132 133 134 135
    return 0;
}
```
## 选项

F
fix bug  
feilong 已提交
136

每日一练社区's avatar
每日一练社区 已提交
137
### A
F
fix bug  
feilong 已提交
138

每日一练社区's avatar
每日一练社区 已提交
139
```c
每日一练社区's avatar
每日一练社区 已提交
140 141 142 143 144 145 146 147 148
int n, m, k;
int data[55][55];
typedef long long LL;

LL ans;
LL mod = 1000000007;
LL cache[55][55][15][15];

LL dfs2(int x, int y, int max, int count)
每日一练社区's avatar
每日一练社区 已提交
149
{
每日一练社区's avatar
每日一练社区 已提交
150 151

    if (cache[x][y][max + 1][count] != -1)
每日一练社区's avatar
每日一练社区 已提交
152
    {
每日一练社区's avatar
每日一练社区 已提交
153 154 155 156 157 158 159 160 161 162 163
        return cache[x][y][max + 1][count];
    }
    LL ans = 0;
    if (x == n || y == m || count > k)
    {
        return 0;
    }
    int cur = data[x][y];
    if (x == n - 1 && y == m - 1)
    {
        if (count == k || (count == k - 1 && cur > max))
每日一练社区's avatar
每日一练社区 已提交
164
        {
每日一练社区's avatar
每日一练社区 已提交
165 166 167 168 169
            ans++;
            if (ans > mod)
            {
                ans %= mod;
            }
每日一练社区's avatar
每日一练社区 已提交
170
        }
每日一练社区's avatar
每日一练社区 已提交
171
        return ans;
每日一练社区's avatar
每日一练社区 已提交
172
    }
每日一练社区's avatar
每日一练社区 已提交
173
    if (cur > max)
每日一练社区's avatar
每日一练社区 已提交
174
    {
每日一练社区's avatar
每日一练社区 已提交
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
        ans += dfs2(x, y + 1, cur, count + 1);
        ans += dfs2(x + 1, y, cur, count + 1);
    }

    ans += dfs2(x, y + 1, max, count);
    ans += dfs2(x + 1, y, max, count);

    cache[x][y][max + 1][count] = ans % mod;
    return ans % mod;
}

void dfs(int x, int y, int max, int count)
{
    if (x == n || y == m || count > k)
    {
        return;
    }
    int cur = data[x][y];
    if (x == n - 1 && y == m - 1)
    {
        if (count == k || (count == k - 1 && cur > max))
每日一练社区's avatar
每日一练社区 已提交
196
        {
每日一练社区's avatar
每日一练社区 已提交
197 198
            ans++;
            if (ans > mod)
每日一练社区's avatar
每日一练社区 已提交
199
            {
每日一练社区's avatar
每日一练社区 已提交
200
                ans %= mod;
每日一练社区's avatar
每日一练社区 已提交
201 202 203
            }
        }
    }
每日一练社区's avatar
每日一练社区 已提交
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
    if (cur > max)
    {
        dfs(x, y + 1, cur, count + 1);
        dfs(x + 1, y, cur, count + 1);
    }

    dfs(x, y + 1, max, count);
    dfs(x + 1, y, max, count);
}

int main()
{
    scanf("%d%d%d", &n, &m, &k);
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j)
        {
            scanf("%d", &data[i][j]);
        }
    }

    memset(cache, -1, sizeof(cache));
    printf("%lld\n", dfs2(0, 0, -1, 0));
每日一练社区's avatar
每日一练社区 已提交
227 228 229 230 231
    return 0;
}
```

### B
F
fix bug  
feilong 已提交
232

每日一练社区's avatar
每日一练社区 已提交
233
```c
每日一练社区's avatar
每日一练社区 已提交
234 235 236 237 238 239
int n, m, k;
int data[55][55];

long long ans;
long long mod = 1000000007;
void dfs(int x, int y, int max, int count)
每日一练社区's avatar
每日一练社区 已提交
240
{
每日一练社区's avatar
每日一练社区 已提交
241
    if (x == n || y == m)
每日一练社区's avatar
每日一练社区 已提交
242
    {
每日一练社区's avatar
每日一练社区 已提交
243
        return;
每日一练社区's avatar
每日一练社区 已提交
244
    }
每日一练社区's avatar
每日一练社区 已提交
245 246
    int cur = data[x][y];
    if (x == n - 1 && y == m - 1)
每日一练社区's avatar
每日一练社区 已提交
247
    {
每日一练社区's avatar
每日一练社区 已提交
248
        if (count == k || (count == k - 1 && cur > max))
每日一练社区's avatar
每日一练社区 已提交
249
        {
每日一练社区's avatar
每日一练社区 已提交
250 251
            ans++;
            if (ans > mod)
每日一练社区's avatar
每日一练社区 已提交
252
            {
每日一练社区's avatar
每日一练社区 已提交
253
                ans %= mod;
每日一练社区's avatar
每日一练社区 已提交
254 255 256
            }
        }
    }
每日一练社区's avatar
每日一练社区 已提交
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
    if (cur > max)
    {
        dfs(x, y + 1, cur, count + 1);
        dfs(x + 1, y, cur, count + 1);
    }

    dfs(x, y + 1, max, count);
    dfs(x + 1, y, max, count);
}

int main()
{
    scanf("%d%d%d", &n, &m, &k);
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j)
        {
            scanf("%d", &data[i][j]);
        }
    }

    dfs(0, 0, -1, 0);

    printf("%lld\n", ans);
每日一练社区's avatar
每日一练社区 已提交
281 282 283 284 285
    return 0;
}
```

### C
F
fix bug  
feilong 已提交
286

每日一练社区's avatar
每日一练社区 已提交
287
```c
每日一练社区's avatar
每日一练社区 已提交
288 289 290 291 292 293
const int N = 55;
const int MOD = 1e9 + 7;
int dp[N][N][13][14];
int g[N][N];
int n, m, k;

每日一练社区's avatar
每日一练社区 已提交
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
int main()
{
    cin >> n >> m >> k;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            cin >> g[i][j];
            g[i][j]++;
        }
    }
    dp[1][1][1][g[1][1]] = 1;
    dp[1][1][0][0] = 1;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            for (int u = 0; u <= k; u++)
            {
                for (int v = 0; v <= 13; v++)
                {
                    dp[i][j][u][v] = (dp[i][j][u][v] + dp[i - 1][j][u][v]) % MOD;
                    dp[i][j][u][v] = (dp[i][j][u][v] + dp[i][j - 1][u][v]) % MOD;
                    if (u > 0 && v == g[i][j])
                    {
                        for (int c = 0; c < v; c++)
                        {
每日一练社区's avatar
每日一练社区 已提交
321
                            dp[i][j][u][v] = (dp[i][j][u][v] + dp[i - 1][j][u - 1][c]) % MOD;
每日一练社区's avatar
每日一练社区 已提交
322 323 324 325 326 327 328 329 330 331 332 333 334 335
                            dp[i][j][u][v] = (dp[i][j][u][v] + dp[i][j - 1][u - 1][c]) % MOD;
                        }
                    }
                }
            }
        }
    }
    int res = 0;
    for (int i = 0; i <= 13; i++)
        res = (res + dp[n][m][k][i]) % MOD;
    cout << res << endl;
    return 0;
}
```