题目来源:1038 Bugs Integrated, Inc.
题意:最多能放多少个2*3的矩形
思路:状态压缩DP啊 初学 看着大牛的代码搞下来的 总算搞懂了 接下来会更轻松吧
3进制代表前2行的状态(i行和i-1行)1代表i-1行占位 2代表i行占位 i-1不管有没有占位都不会影响的0代表i行和i-1行都空闲
然后枚举状态dfs更新状态 话说就不能没写深搜了 有点不会了
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int dp[2][60000];
int a[155][12];
int b[115][12];
int n, m;
int get(int k)
{
int ans = 0;
for(int i = m-1; i >= 0; i--)
{
ans *= 3;
ans += b[k][i];
}
return ans;
}
int get2(int x, int k)
{
for(int i = 0; i < m; i++)
{
b[k][i] = x%3;
x /= 3;
}
}
void dfs(int l, int i, int x)
{
dp[l][get(1)] = max(dp[l][get(1)], x);
//printf("***%d", dp[l][get(1)]);
if(i >= m)
return;
if(i < m-2 && !b[1][i] && !b[1][i+1] && !b[1][i+2])
{
//puts("sfa");
b[1][i] = b[1][i+1] = b[1][i+2] = 2;
dfs(l, i+3, x+1);
b[1][i] = b[1][i+1] = b[1][i+2] = 0;
}
if(i < m-1 && !b[1][i] && !b[1][i+1] && !b[0][i] && !b[0][i+1])
{
//puts("dfs");
b[1][i] = b[1][i+1] = 2;
dfs(l, i+2, x+1);
b[1][i] = b[1][i+1] = 0;
}
dfs(l, i+1, x);
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
memset(a, 0, sizeof(a));
int k;
scanf("%d %d %d", &n, &m, &k);
int s = 1;
for(int i = 0; i < m; i++)
s *= 3;
for(int i = 0; i < k; i++)
{
int x, y;
scanf("%d %d", &x, &y);
a[--x][--y] = 1;
}
memset(dp, -1, sizeof(dp));
for(int i = 0; i < m; i++)
{
b[0][i] = a[0][i] + 1;
}
dp[1][get(0)] = 0;
int l = 1, r = 0;
for(int i = 1; i < n; i++)
{
l ^= 1;
r ^= 1;
memset(dp[l], -1, sizeof(dp[l]));
for(int j = 0; j < s; j++)
{
if(dp[r][j] == -1)
continue;
get2(j, 0);
for(int t = 0; t < m; t++)
{
if(a[i][t])
b[1][t] = 2;
else
b[1][t] = b[0][t]-1;
if(b[1][t] < 0)
b[1][t] = 0;
}
dfs(l, 0, dp[r][j]);
}
}
int ans = 0;
for(int i = 0; i < s; i++)
ans = max(ans, dp[l][i]);
printf("%d\n", ans);
}
return 0;
}