开启掘金成长之旅!这是我参与「掘金日新计划·2月更文挑战」的第18天,点击查看活动详情
Codeforces 1472 D - Even-Odd Game(贪心思想,博弈)
题意:
Alice和Bob在数组a中的n个整数,选择数字
Alice如果选择偶数,那么将这个数字加到Alice的得分中,如果选择了奇数,则不计分
Bob如果选择奇数,那么将这个数字加到Bob的的分钟,如果选择了偶数,则不计分
两者皆采取最优策略,Alice先走,得分多者获胜,如果是平局则输出Tie。
题解:
两者都是最优策略,所谓最优策略就是,判断 我方得分的最大值与对方得分的最大值 的大小,如果我方得分最大值 小于 对方得分的最大值,自然是先把对方的拿掉,反之先拿自己的,让自己加分。
那么让这个序列从大到小排序,Alice先拿,那么序列下标是1~n的,那么:
- 如果是序列下标为奇数,那么就是Alice拿,如果当前数字是偶数,那么就将该数字加到得分,如果当前数字是奇数,不做任何操作。
- 如果是序列下标为偶数,那么就是Bob拿,如果当前数字是奇数,那么就将该数字加到得分,如果当前数字是偶数,不做任何操作。
const int N = 200010;
int a[N];
signed main() {
int t, cin >> t;
while (t--) {
int n, cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
sort(a + 1, a + n + 1, cmp); //从大到小排序
int Alice = 0, Bob = 0;
for (int i = 1; i <= n; i++) {
if (i % 2 && a[i] % 2 == 0) Alice += a[i];//偶数就加进去
else if (a[i] % 2) Bob += a[i];//奇数就加进去
}
if (Alice > Bob) printf("Alice\n");
else if (Alice < Bob) printf("Bob\n");
else printf("Tie\n");
}
return 0;
}
POJ 2279 杨老师的照相排列 (线性DP)
求合影的方案数?
注意题目范围:k ≤ 5,那么可以最多有5排
开个五维数组 表示每行分别站了 个人的方案数,各个维度均满足线性增长的形式。
当安排一名新的学生时:
- 前面一行的数量要大于当前行的数量
初始化边界:
const int M = 31;
ll f[M][M][M][M][M];
int s[6];
int main() {
int k;
while (cin >> k && k) {
memset(s, 0, sizeof s);
for (int i = 1; i <= k; i++) cin >> s[i];
memset(f, 0, sizeof f);
f[0][0][0][0][0] = 1; //初始化边界
for (int a1 = 0; a1 <= s[1]; a1++) { //状态转移:
for (int a2 = 0; a2 <= s[2]; a2++) {
for (int a3 = 0; a3 <= s[3]; a3++) {
for (int a4 = 0; a4 <= s[4]; a4++) {
for (int a5 = 0; a5 <= s[5]; a5++) {
if (f[a1][a2][a3][a4][a5] == 0) continue;
if (a1 < s[1]) f[a1 + 1][a2][a3][a4][a5] += f[a1][a2][a3][a4][a5];
if (a2 < s[2] && a1 > a2) f[a1][a2 + 1][a3][a4][a5] += f[a1][a2][a3][a4][a5];
if (a3 < s[3] && a2 > a3) f[a1][a2][a3 + 1][a4][a5] += f[a1][a2][a3][a4][a5];
if (a4 < s[4] && a3 > a4) f[a1][a2][a3][a4 + 1][a5] += f[a1][a2][a3][a4][a5];
if (a5 < s[5] && a4 > a5) f[a1][a2][a3][a4][a5 + 1] += f[a1][a2][a3][a4][a5];
}
}
}
}
}
cout << f[s[1]][s[2]][s[3]][s[4]][s[5]] << endl;
}
return 0;
}