HDU5900-QSC and Master-区间DP+区间覆盖DP

地址 http://acm.hdu.edu.cn/showproblem.php?pid=5900

2016ICPC沈阳赛区网络赛

题意:一个队列,每个点有key[i]和value[i],位置相邻且key不互质的两个点可以被取走,取走后,剩下点自动连接起来。

    问取走的value和最大

题解:1.对于所有的区间,用区间DP求出能否 整个 区间取走

      枚举区间长度

      对于[s,e] 的区间,要么由两个比这短的区间拼凑而成,要么s和e可以不互质,且[s+1,e-1]可以取走,特判长度为2的时候。

   2.对于所有能取走的区间,有区间覆盖(覆盖一次)问题

   3.DP解决问题2

      对于所有区间按照终点排序

      对于不是终点的i,dp[i] = dp[i-1]

      对于是终点的i,dp[i] = max( dp[ i - 1 ] , { E.Svalue | E.end == i } )

      坐标轴上的单向最短(长)路问题和这个类似

沈阳站赛前复习,希望自己沈阳加油。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 using namespace std;
 6 long long a[333];
 7 long long b[333];
 8 long long sum[333];
 9 long long dp[333];
10 struct Edge
11 {
12     int s,e;
13     long long val;
14 }E[93333];
15 int ife[333][333];
16 long long gcd(long long aa, long long bb)
17 {
18         return bb == 0 ? aa : gcd(bb,aa % bb);
19 }
20 bool com(Edge A,Edge B)
21 {
22         return A.e < B.e;
23 }
24 void addedge(int s, int e)
25 {
26     ife[s][e] = 1;
27     E[cnt].s = s;
28     E[cnt].e = e;
29     E[cnt].val = sum[e] - sum[s-1];
30     cnt++;
31 }
32 int main()
33 {
34      int T;
35      //freopen("in.txt","r",stdin);
36      cin >> T;
37      while (T--)
38      {
39         memset(E,0,sizeof(E));
40         memset(ife,0,sizeof(ife));
41         memset(dp,0,sizeof(dp));
42         sum[0] = 0;
43         int N;
44         cin >> N;
45         for (int i = 1; i<= N; i++)
46         {
47             scanf("%lld",&a[i]);
48         }
49         for (int i = 1; i<= N; i++)
50         {
51             scanf("%lld",&b[i]);
52             sum[i] = sum[i-1] + b[i];
53         }
54         int cnt = 1;
55         //区间DP建边
56         //如果s,e之间 能通过某种方式全部取出,那么s,e区间建边
57         for (int i = 1; i<=N; i+=2)
58         {
59             for (int s = 1; s+i<=N; s++)
60             {
61                 int e = s+i;
62                 if (ife[s][e] == 1) continue;
63                 if (gcd(a[s],a[e]) != 1LL && (i == 1 || ife[s+1][e-1] == 1))
64                 {
65                     addedge(s,e);
66                     continue;
67                 }
68                 for (int l = s + 1 ;l <= e-2; l += 2 )
69                 {
70                     if (ife[s][l] == 1 && ife[l+1][e] == 1)
71                     {
72                         addedge(s,e);
73                         break;
74                     }
75                 }
76             }
77         }
78         //每个点只能被选一次,转换为区间一次性覆盖,所有的区间都已经经过区间dp求出
79         //区间一次性覆盖 可以用DP求
80         sort(E+1,E+cnt,com);
81         for (int i = 1; i<cnt;)
82         {
83             int te = E[i].e;
84             while (E[i].e == te)
85             {
86                 dp[te] = max(dp[te],dp[E[i].s-1] + E[i].val);
87                 i++;
88             }
89             for (int j = te+1 ; j <= E[i].e ; j++)
90                 dp[j] = dp[j-1];
91         }
92         //此处不要输出dp[N],因为dp的范围就是最后一条边的终点
93         cout << dp[E[cnt-1].e] <<endl;
94      }
95 }
时间: 2024-08-01 07:02:48

HDU5900-QSC and Master-区间DP+区间覆盖DP的相关文章

HDU5900 QSC and Master(区间DP + 最小费用最大流)

题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5900 Description Every school has some legends, Northeastern University is the same. Enter from the north gate of Northeastern University,You are facing the main building of Northeastern University.

2016 年沈阳网络赛---QSC and Master(区间DP)

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5900 Problem Description Every school has some legends, Northeastern University is the same. Enter from the north gate of Northeastern University,You are facing the main building of Northeastern Universi

hdu 5900 QSC and Master 区间dp

QSC and Master Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description Every school has some legends, Northeastern University is the same. Enter from the north gate of Northeastern University,You are

[HDOJ5900]QSC and Master(区间dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5900 巧妙的地方在于第四个转移,假如dp(i,j)区间内所有的都取了,那状态的值应该是s(j)-s(i-1) 1 #include <bits/stdc++.h> 2 using namespace std; 3 #define fr first 4 #define sc second 5 #define cl clear 6 #define BUG puts("here!!!"

HDU 2836 (离散化DP+区间优化)

Reference:http://www.cnblogs.com/wuyiqi/archive/2012/03/28/2420916.html 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2836 题目大意:计算序列有多少种组合,每个组合至少两个数,使得组合中相邻两个数之差不超过H,序列有重复的数.MOD 9901. 解题思路: 朴素O(n^2) 以样例1 3 7 5为例,如果没有重复的数. 设dp[i]前n个数的方案数,初始化为1. 那么fo

区间选点+区间覆盖

区间选点+区间覆盖 区间选点问题(选择最少的点,使得每个区间都至少有k个点) 将这些区间[l,r]先按照r从小到大排序,再按照l从大到小排序.选点尽量选择靠近右边界的点.然后按照这个排序后的区间进行遍历,用一个变量来存放遍历过程中上个区间的右边界,然后碰到一个新的区间的时候需要分两种情况讨论:1.这个区间和上个区间有相交的部分,那么就需要判断一下上次选择的点有多少在这个区间内,这些点满足要求吗?不满足的话还需要在这个区间内选点2.这个区间和上个区间没有交集,那么这个区间就需要选点. 上述策略可以

codeforces Good bye 2016 E 线段树维护dp区间合并

题目大意:给你一个字符串,范围为'0'~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问,最少删除多少个字符,使得串中符合ugly串? 思路:定义dp(i, j),其中i=5,j=5,因为只需要删除2016当中其中一个即可,所以一共所需要删除的字符和需要的字符为20176,因此i和j只要5就够了. 然后转移就是dp(i,i) = 0, 如果说区间大小为1的话,那么如果是2017中的一个,那么就是dp(pos, pos+1) = 0, dp(pos,pos) =

2017.8.15 [Haoi2016]字符合并 区间dp+状压dp

[题目描述] 有一个长度为n的01串,你可以每次将相邻的k个字符合并,得到一个新的字符并获得一定分数.得到的新字符和分数由这k个字符确定.你需要求出你能获得的最大分数. [输入格式] 第一行两个整数n,k. 接下来一行长度为n的01串,表示初始串.输入的的相邻字符之间用一个空格隔开. 接下来2k行,每行一个字符ci和一个整数wi,ci表示长度为k的01串连成二进制后按从小到大顺序得到的第i种合并方案得到的新字符, wi表示对应的第i种方案对应获得的分数. [输出格式] 输出一个整数表示答案. [

HDU6447 YJJ&#39;s Salesman-2018CCPC网络赛-线段树求区间最值+离散化+dp

目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog Problem:Portal传送门 ?原题目描述在最下面. ?1e5个点,问从(0,0)走到(1e9,1e9)的最大收益. ?当你从(u-1,v-1)走到(u,v)时,你可以获得点(u,v)的权值. Solution: ?十分详细了. ?直接线段树区间最值.当然也可以树状数组,不能st表. ?\(dp[i] = max(query\_max(0,dp[i]-1,1)+val[i] ,