A: Broadcast Stations
题目大意
给定一棵树,选一些节点 i i ,赋予 表示节点能覆盖到距离不超过 P(i) P ( i ) 的所有点,如果 P(i)=0 P ( i ) = 0 ,不能覆盖本身,问 min∑P(i) min ∑ P ( i ) 。
题解
树形DP。
B: Connect3
题目大意
有一个4*4的竖着放的板,每次可以选择一列从上方放一个黑色或白色的圆盘,圆盘会从下往上磊。已知黑方先选择第x列放了黑色圆盘,问白方最后选择第b列圆盘掉在了第a行恰好白方胜利的情况数有多少。胜利指的是横着、斜着、竖着连续3个圆盘颜色相同即为胜利。
(图片从维基找的)
题解
因为范围只有4*4,又有情况的限制,因此合法的情况不会很多,因此我们全部爆搜出来就好了。。
#include <cstdio>
#include <set>
#include <utility>
#define FOR(i,j,k) for(i=j;i<=k;++i)
using namespace std;
set<pair<int, int>> vis;
int a, b, ans = 0;
int board[5][5];
int loc(int x, int y)
{
return (x - 1) * 4 + (y - 1);
}
bool win(int p)
{
int i, j;
FOR(i,1,4) FOR(j,1,4)
{
if (i <= 2 && board[i][j] == p && board[i + 1][j] == p && board[i + 2][j] == p)
return true;
if (j <= 2 && board[i][j] == p && board[i][j + 1] == p && board[i][j + 2] == p)
return true;
if (i <= 2 && j <= 2 && board[i][j] == p && board[i + 1][j + 1] == p && board[i + 2][j + 2] == p)
return true;
if (i <= 2 && j >= 3 && board[i][j] == p && board[i + 1][j - 1] == p && board[i + 2][j - 2] == p)
return true;
}
return false;
}
void dfs(int black, int white, int turn, int x, int y)
{
int i, j;
if (vis.count(make_pair(black, white)))
return;
vis.insert(make_pair(black, white));
if (win(2) || win(3))
{
if (win(