Wai Doudou
Input
The two integers N and M in the first row are the side lengths of the matrix. An integer D in the second line is the total number of beans. The third line contains D integers V1 to VD, which are the scores of each bean. Next, there is an N × M character matrix on the Nth row to describe the state of the game matrix, 0 means space and # means obstacle. The numbers 1 to 9 respectively indicate the corresponding number of beans.
Output
Contains only an integer, the highest possible score.
Sample Input
3 8
3
30 -100 30
00000000
010203#0
00000000
Sample Output
38
Hint
50% of the data satisfies \ (1≤D≤3 \) .
100% of the data satisfies \ (1≤D≤9, 1≤N, M≤10, -10000≤V_i≤10000 \) .
answer
Problem-solving ideas
This question seems quite hard, is quite hard
but to see the data range \ (1≤D≤9,1≤N, M≤10, -10000≤V_i≤10000 \
) quite small
considering violent state of compression DP
with A string of binary numbers represents the inclusion of each bean.
For example, \ (11010 \) means to include beans 2, 4, and 5.
There is also to determine whether a point is in the polygon.
Make any ray from this point. If the number of intersection points with the polygon is odd, it is inside the polygon, otherwise it is not
If this ray happens to cross the edge, then there is no way to find the number of intersections, so we only count the ones that have crossed this ray vertically (only for this question).
Look at the following example
0******0
0*0000*0
0*1****0
0***0000
Like this, 1 has passed 4 points to the right, but 1 actually
counts the points below this edge when it is counted in this polygon
Code
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
const int N = 12;
int n, m, d, M, a[N], sum[1<<N], f[N][N][1<<N], v[N][N][1<<N], ans;
int dx[4] = {0, 0, 1, -1}, dy[4] = {1, -1, 0, 0}, fx[N], fy[N], cnt;
char c[N][N];
struct node {
int x, y, s;
node(int a, int b, int c) {
x = a; y = b; s = c;
}
};
queue<node> q;
void bfs(int x, int y) {
memset(f, 0x3f, sizeof(f));
memset(v, 0, sizeof(v));
q.push(node(x, y, 0));
f[x][y][0] = 0;
while (!q.empty()) {
node b = q.front(); q.pop();
v[b.x][b.y][b.s] = 1;
for(int i = 0; i < 4; i++) {
int xx = b.x + dx[i], yy = b.y + dy[i], s = b.s;
if (xx < 1 || yy < 1 || xx > n || yy > m || c[xx][yy] != '0') continue;
if (i >= 2)
for(int j = 1; j <= d; j++)
if (fx[j] == min(b.x, xx) && yy > fy[j])
s ^= 1 << (j - 1);
if (!v[xx][yy][s] && f[xx][yy][s] > f[b.x][b.y][b.s]) {
v[xx][yy][s] = 1;
f[xx][yy][s] = f[b.x][b.y][b.s] + 1;
q.push(node(xx, yy, s));
}
}
}
for(int i = 0; i < M; i++)
ans = max(ans, sum[i] - f[x][y][i]);
}
int main() {
scanf("%d%d%d", &n, &m, &d);
for(int i = 1; i <= d; i++)
scanf("%d", &a[i]);
M = 1 << d;
for(int i = 0; i < M; i++)
for(int j = 1; j <= d; j++)
if (i & (1 << (j - 1)))
sum[i] += a[j];
for(int i = 1; i <= n; i++)
scanf("%s", c[i]+1);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
if (c[i][j] > '0' && c[i][j] <= '9')
fx[c[i][j]-'0'] = i, fy[c[i][j]-'0'] = j;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
if (c[i][j] == '0') bfs(i, j);
printf("%d", ans);
return 0;
}