喵哈哈村的挑衅
来源:互联网 发布:自学网下载软件 编辑:程序博客网 时间:2024/04/27 16:05
题目大意:有两排物品,每排都有n个,青君和狗哥轮流从每排的两侧拿任意一个物品。青君先手,假设狗哥绝顶聪明,青君所拿物品价值之和最大为多少?
分析:区间DP。
状态:dp[x1][y1][x2][y2],表示在区间[x1, y1]和区间[x2, y2]中能取到的最大值。
状态转移方程:有四种情况,分别为x1+1,y1-1,x2+1,y2-1。显然取四个中最小的那个。
下面的代码里,分别用a,b数组来表示两排的前缀和。
#include <cstdio>#include <algorithm>#include <cstring>using namespace std;int n, A[30], B[30];int d[30][30][30][30], v[30][30][30][30];int DP(int L1, int R1, int L2, int R2) { if (v[L1][R1][L2][R2]) return d[L1][R1][L2][R2]; v[L1][R1][L2][R2] = 1; int sum = 0, ans = 0; if (L1 <= R1) sum += A[R1] - A[L1-1]; if (L2 <= R2) sum += B[R2] - B[L2-1]; if (L1 <= R1) { ans = max(ans, sum - DP(L1+1, R1, L2, R2)); ans = max(ans, sum - DP(L1, R1-1, L2, R2)); } if (L2 <= R2) { ans = max(ans, sum - DP(L1, R1, L2+1, R2)); ans = max(ans, sum - DP(L1, R1, L2, R2-1)); } return d[L1][R1][L2][R2] = ans;}int main() { while (scanf("%d", &n) != EOF) { memset(d, 0, sizeof(d)); memset(v, 0, sizeof(v)); for (int i = 1; i <= n; i++) { int tmp; scanf("%d", &tmp); A[i] = A[i-1] + tmp; } for (int i = 1; i <= n; i++) { int tmp; scanf("%d", &tmp); B[i] = B[i-1] + tmp; } printf("%d\n", DP(1, n, 1, n)); } return 0;}
0 0
- 喵哈哈村的挑衅
- 喵哈哈村的挑衅
- 喵哈哈村的挑衅(区间DP)
- DP ACdream 喵哈哈村的挑衅
- ACDream dp专题 B - 喵哈哈村的挑衅
- 办公室里的“挑衅”
- 喵哈哈村的魔法石
- 喵哈哈村的种花魔法
- qscoj:喵哈哈村的卢西奥
- 喵哈哈村的卢西奥(dfs)
- 一个无知人对Linux的挑衅
- 曾哥传 第六话 泰拳的挑衅
- 喵哈哈村的括号序列(初学栈)
- qscoj:喵哈哈村的狼人杀大战(5)
- 喵哈哈村的狼人杀大战(5)
- qscoj:喵哈哈村的烧烤店(阶梯博弈)
- 喵哈哈村的打印机游戏(区间DP)
- qscoj 喵哈哈村的打印机游戏(区间dp)
- DirectFb 标准键盘键值查找过程
- LeetCode || Reverse Linked List II
- 系统调用
- makefile
- C语言之函数调用13—递归法求N阶勒让德多项式的值
- 喵哈哈村的挑衅
- LoaderManager的使用
- UE4学习笔记8th
- linux常用命令整理
- java多线程(生产消费)
- 图灵机器人
- 2015.07.28总结
- linux初学(十一)之linux获取帮助
- OCR字符识别