JZOJ #4707 / CODEFORCES #704 B.Ant Man

题目描述:

这题改编自cf704b,在数轴上有n个点,从一个点跳到另一个点的收益是两点的距离和给出的数组对应下标的值,并且往左和往右的数组不同。要求从一个点起跳,经过每个点刚好一次,最后回到原点,使得收益最大。

解题思路:

因为每个点的贡献只跟跳过来的方向有关,与哪个点跳过来无关。所以可以考虑dp,因为最好是一个环,所以每个点的出度和入度都是一。设f[i][j][k]表示前i个点还有j个点的出边未匹配,k个点的入边未匹配。考虑i+1个点,有四种情况,左进左出,右进右出,左进右出,右进左出,相应的状态是f[i + 1][j - 1][k - 1]、f[i + 1][j + 1][k]、f[i + 1][j][k],注意到j和k是恒等的,所以可以简化到二维。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define i64 long long
 5 using namespace std;
 6
 7 const int N = 5e3 + 10;
 8 const i64 inf = 1e15;
 9 int n, x[N], a[N], b[N], c[N], d[N];
10 i64 f[N][N];
11
12 int main() {
13     scanf("%d", &n);
14     for (int i = 1; i <= n; i ++) scanf("%d", &x[i]);
15     for (int i = 1; i <= n; i ++) scanf("%d", &a[i]);
16     for (int i = 1; i <= n; i ++) scanf("%d", &b[i]);
17     for (int i = 1; i <= n; i ++) scanf("%d", &c[i]);
18     for (int i = 1; i <= n; i ++) scanf("%d", &d[i]);
19     for (int i = 0; i <= n; i ++)
20         for (int j = 0; j <= n; j ++) f[i][j] = -inf;
21     f[0][0] = 0;
22     for (int i = 0; i < n; i ++)
23         for (int j = 0; j <= i; j ++) {
24             if (j) {
25                 f[i + 1][j - 1] = max(f[i + 1][j - 1], f[i][j] + 2 * x[i + 1] + a[i + 1] + c[i + 1]);
26                 f[i + 1][j] = max(f[i + 1][j], f[i][j] + a[i + 1] + d[i + 1]);
27                 f[i + 1][j] = max(f[i + 1][j], f[i][j] + b[i + 1] + c[i + 1]);
28             }
29             f[i + 1][j + 1] = max(f[i + 1][j + 1], f[i][j] - 2 * x[i + 1] + d[i + 1] + b[i + 1]);
30         }
31     printf("%lld", f[n][0]);
32     return 0;
33 }
时间: 2024-10-21 08:14:09

JZOJ #4707 / CODEFORCES #704 B.Ant Man的相关文章

【CodeForces】704 B. Ant Man

[题目]B. Ant Man [题意]给定n个人的xi,ai,bi,ci,di,起点为s,终点为e,移动: In simpler words, jumping from i-th chair to j-th chair takes exactly: |xi?-?xj|?+?ci?+?bj seconds if j?<?i. |xi?-?xj|?+?di?+?aj seconds otherwise (j?>?i). 求中间经过所有点恰好一次的最小代价. [算法]动态规划 [题解]很巧妙的DP状

【贪心】Codeforces 704B &amp; 705D Ant Man

题目链接: http://codeforces.com/problemset/problem/704/B 题目大意: 给N个点,起点S终点T,每个点有X,A,B,C,D,根据I和J的X坐标可得I到J的距离计算公式:(题目描述的那个i<j有错!害我WA了好几次) |xi - xj| + ci + bj seconds if x[j] < x[i]. |xi - xj| + di + aj seconds otherwise (x[j] > x[i]). 求从起点到终点,经过N个点恰好一次的

JZOJ #4708 / CODEFORCES #217 E.Alien DNA

题目描述: 这题改编自CF217E,给出一串字符串,有n个操作,将区间[l, r]的字符中编号为奇数的写下,再把偶数的写在后面,然后把它们插入r和r + 1之间,问最后字符串的前k位. 解题思路: 因为前面的操作不会对后面的操作有影响,所以我们考虑把操作倒过来做.相应的,一开始就只有k个位置有效,然后对于操作[l, r],就把[r + 1, r + (r - l + 1)]标记为已操作,并记录每一位是哪一位转移过来的.然后对于前一个操作,就只能做那些未标记的位置.相当于对未标记的位置重标号,然后

Codeforces 29D Ant on the Tree 树的遍历 dfs序

题目链接:点击打开链接 题意: 给定n个节点的树 1为根 则此时叶子节点已经确定 最后一行给出叶子节点的顺序 目标: 遍历树并输出路径,要求遍历叶子节点时按照给定叶子节点的先后顺序访问. 思路: 给每个节点加一个优先级. 把最后一个叶子节点到父节点的路径上的点优先级改为1 把倒数第二个叶子节点到父节点的路径上的点优先级改为2 如此每个点就有一个优先级,每个访问儿子节点时先访问优先级大的即可 对于无解的判断:得到的欧拉序列不满足输入的叶子节点顺序即是无解. #include <cstdio> #

CodeForces 29D Ant on the Tree

给一颗树,1为根,要求遍历树上所有点,给出叶子结点的访问顺序,限制每条边至多访问两次. 首先这是一棵树,那么两点之间的路线是确定的,所以我第一遍dfs预处理出从根节点到每个叶子的路径保存,以便后面输出. 那么就按照题目要求输出叶子结点的顺序依次输出,然后从一个叶子到下一个叶子的时候,从他们的最近公共祖先转折,所以我还预处理了相邻两个叶子结点的LCA. #include <iostream> #include <cstdlib> #include <cstring> #i

Codeforces Round #271 (Div. 2) F.Ant colony(线段树 + 统计区间内某数的个数)

F. Ant colony Mole is hungry again. He found one ant colony, consisting of n ants, ordered in a row. Each ant i (1 ≤ i ≤ n) has a strength si. In order to make his dinner more interesting, Mole organizes a version of «Hunger Games» for the ants. He c

Codeforces G. Ant colony

题目描述: F. Ant colonytime limit per test1 secondmemory limit per test256 megabytesinputstandard inputoutputstandard output Mole is hungry again. He found one ant colony, consisting of n ants, ordered in a row. Each ant i (1 ≤ i ≤ n) has a strength si.

Codeforces 474F - Ant colony

注意到每个区间生存下来的蚂蚁的长度等于区间的gcd 于是可以先预处理出区间的gcd 然后二分查找就好了 预处理gcd我这里用的是倍增法 总的时间复杂度O(NlogN) /* Cf 271F 倍增求区间GCD 对下标二分 时间复杂度O(NlogN) */ #include <iostream> #include <algorithm> #include <vector> #include <map> using namespace std; const int

【CodeForces】704 C. Black Widow 动态规划+模拟

[题目]C. Black Widow [题意]给定一个表达式,形式为(...)^(...)^......^(...)=1(n个括号),括号中为1~2个值取或.有m个变量,给出表达式的值为xi或 !xi,xi只能为0或1,求变量赋值使得表达式成立的方案数.每个变量至多出现两次.n,m<=10^5. [算法]动态规划+模拟 [题解]每个括号视为一个点,对于同时出现在两个括号内的变量将两个点连边(边须记两边异同).由于每个变量至多出现两次,所以一条边就可以代表一个变量. 由于每个括号至多两个变量,所以