2014 ACM/ICPC 亚洲区 北京站
题目链接 2014北京区域赛
Problem A
Problem B
直接DFS+剪枝
剪枝条件:当前剩余的方块数量cnt < 2 * max{a[i]} - 1,则停止往下搜。
因为这样搜下去接下来肯定会出现相邻方块颜色相同的情况。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) #define MP make_pair #define fi first #define se second typedef long long LL; const int N = 205; int f[N][N]; int a[N], b[N]; int n; int T; int ca = 0; int dp(int l, int r){ if (l > r) return 0; if (~f[l][r]) return f[l][r]; int &ret = f[l][r]; ret = 1 << 30; rep(i, l, r) ret = min(ret, dp(l, i - 1) + a[i] + b[l - 1] + b[r + 1] + dp(i + 1, r)); return ret; } int main(){ scanf("%d", &T); while (T--){ memset(f, -1, sizeof f); scanf("%d", &n); memset(a, 0, sizeof a); memset(b, 0, sizeof b); rep(i, 1, n) scanf("%d", a + i); rep(i, 1, n) scanf("%d", b + i); printf("Case #%d: %d\n", ++ca, dp(1, n)); } return 0; }
Problem C
Problem D
考虑区间DP
$f[i][j] = min(f[i][k-1] + a[k] + b[k - 1] + b[k + 1] + f[k + 1][j])$
边界条件处理并不麻烦,
记忆化搜索就可以了。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) #define MP make_pair #define fi first #define se second typedef long long LL; const int N = 205; int f[N][N]; int a[N], b[N]; int n; int T; int ca = 0; int dp(int l, int r){ if (l > r) return 0; if (~f[l][r]) return f[l][r]; int &ret = f[l][r]; ret = 1 << 30; rep(i, l, r) ret = min(ret, dp(l, i - 1) + a[i] + b[l - 1] + b[r + 1] + dp(i + 1, r)); return ret; } int main(){ scanf("%d", &T); while (T--){ memset(f, -1, sizeof f); scanf("%d", &n); memset(a, 0, sizeof a); memset(b, 0, sizeof b); rep(i, 1, n) scanf("%d", a + i); rep(i, 1, n) scanf("%d", b + i); printf("Case #%d: %d\n", ++ca, dp(1, n)); } return 0; }
Problem E
Problem F
Problem G
Problem H
Problem I
Problem J
Problem K