~~~题面~~~

题解:

  感到此题非常的神奇。。。看了大佬的题解才懂的。

  首先建模:

  先把所有队伍的出去回来时间都放在一个数组里,然后排序,从左到右扫一边,给每个队伍都建一个带权点,进行如下操作:

  (s表示出发,t表示回家, len表示两个点之间的时间差)  

  1,对于s --- > t的情况,如果两者属于一个队伍,那么给这个队伍加上len,表示如果给这个队伍钥匙可以获得的贡献。

    如果两者不属于同一个队伍,那么在这两个队伍之间连一条边权为len的边,表示如果同时给这2个队伍钥匙可以获得的贡献。

  2,对于s ---> s的情况,给左边的队伍加上len,表示如果给左边队伍钥匙可以获得的贡献。

  3,对于t ---> t的情况,给右边队伍加上len,表示如果给右边队伍钥匙可以获得的贡献。

  4,对于t ---> s的情况,直接给ans += len,因为不需要钥匙就可以获得这个贡献。

  然后考虑如何DP。

  我们观察到每个点最多只有一条入边,最多只有一条出边,因此这些点和边构成了由一堆链组成的图。而这些链两两不相交(不互相干扰)

  因此我们只需要保证在DP时,一条链中的点都按顺序放在一起即可。所以我们对整张图做一个拓扑排序,最后得到的DP顺序应该是类似这样的:(可能有点单独成链)

  相当于把所有链一一放好,然后DP。

  那么如何转移呢?

  设f[i][j][0/1]表示DP到i位,当前选了j个点,当前点选or不选的贡献。

  那么对于不相连的点,直接更新即可,

  对于相连的点,如果用f[i - 1][j - 1][1]更新f[i][j][1],那么还需要加上两点之间边的边权,表示两个点同时选带来的多余贡献。

  最后的答案等于ans = d[n * 2] - d[1] - ans - max(f[i][j][1], f[i][j][0]);

  d[n * 2] - d[1]是在获取整个线段的长度,减去ans是在减掉一开始就有的贡献(无需钥匙的),max(f[i][j][0], f[i][j][1])是给钥匙带来的贡献,相减后剩下的就是开门的天数。

  (一遍A,感到非常愉悦,而且速度还可以)

 #include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 2100
#define ac 5000
#define LL long long int n, k, cnt, ans;
int power[AC], Next[AC], last[AC];
int in[AC], d[AC], tot;//存下DP序列
LL s[AC], f[AC][AC][];
bool z[AC];
//DP到i位,选了j个点,当前点选与不选,s是当前点的向后的边的边权
struct node{
int x, id;
bool z;
}p[ac]; inline int read()
{
int x = ;char c = getchar();
while(c > '' || c < '') c = getchar();
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x;
} inline bool cmp(node a, node b)
{
return a.x < b.x;
} inline void upmax(int &a, int b)
{
if(b > a) a = b;
} void dfs(int x)
{
d[++tot] = x, z[x] = true;
while(Next[x]) d[++tot] = Next[x], x = Next[x], z[x] = true;
} void pre()
{
n = read(), k = read();
for(R i = ; i <= n; i ++)
{
p[++cnt] = (node){read(), i, };
p[++cnt] = (node){read(), i, };
}
sort(p + , p + cnt + , cmp);
int b = * n;
for(R i = ; i < b; i ++)
{
int len = p[i + ].x - p[i].x, x = p[i].id, y = p[i + ].id;
if(!p[i].z && p[i + ].z)
{
if(x == y) power[p[i].id] += len;
else Next[x] = y, last[y] = x, s[x] = len, ++ in[y];
}
else if(!p[i].z && !p[i + ].z) power[x] += len;
else if(p[i].z && p[i + ].z) power[y] += len;
else ans += len;
}
} void work()
{
int b = * n;
for(R i = ; i < b; i ++) //类似于拓扑排序,要没有入度才行
if(!z[p[i].id] && !in[p[i].id]) dfs(p[i].id);
for(R i = ; i <= n; i ++)//枚举点
{
for(R j = ; j <= k; j ++)
{
f[i][j][] = max(f[i - ][j][], f[i - ][j][]);
if(last[d[i]]) f[i][j][] = max(f[i - ][j - ][], f[i - ][j - ][] + s[last[d[i]]]) + power[d[i]];
else f[i][j][] = max(f[i - ][j - ][], f[i - ][j - ][]) + power[d[i]];
}
}
printf("%lld\n", p[n * ].x - ans - p[].x - max(f[n][k][], f[n][k][]));
} int main()
{
freopen("in.in", "r", stdin);
pre();
work();
fclose(stdin);
return ;
}

[LG4890]Never·island DP的更多相关文章

  1. cf.301.D. Bad Luck Island(dp + probabilities)

    D. Bad Luck Island time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  2. CodeForces 540D Bad Luck Island (DP)

    题意:一个岛上有石头,剪刀和布,规则就不用说了,问你最后只剩下每一种的概率是多少. 析:很明显的一个概率DP,用d[i][j][k]表示,石头剩下 i 个,剪刀剩下 j 个,布剩下 k 个,d[r][ ...

  3. HDU-3502-Huson&#39;s Adventure Island(BFS+如压力DP)

    Problem Description A few days ago, Tom was tired of all the PC-games, so he went back to some old F ...

  4. bzoj1791: [Ioi2008]Island 岛屿 单调队列优化dp

    1791: [Ioi2008]Island 岛屿 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 1826  Solved: 405[Submit][S ...

  5. P4890 Never·island(dp)

    P4890 Never·island 求门开的最小时间,其实也就是求门关的最大时间. 坐标这么大....显然坐标要离散化 离散化排序后,我们发现x轴被这些点划分成若干条线段$(l,r)$,并且有4种情 ...

  6. P4381 [IOI2008]Island(基环树+单调队列优化dp)

    P4381 [IOI2008]Island 题意:求图中所有基环树的直径和 我们对每棵基环树分别计算答案. 首先我们先bfs找环(dfs易爆栈) 蓝后我们处理直径 直径不在环上,就在环上某点的子树上 ...

  7. Codeforces Round #301 (Div. 2) D. Bad Luck Island 概率DP

    D. Bad Luck Island Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/540/pr ...

  8. CF#301 D:Bad Luck Island (概率dp)

    D:Bad Luck Island 一个岛上有r个石头,s个剪子,p个布,他们之间随机挑出两个相遇,如果不是相同物种,就会有一个消失,分别求出最后这座岛上只剩下一个物种的概率. 我们用dp[i][j] ...

  9. CF 540D——Bad Luck Island——————【概率dp】

    Bad Luck Island time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...

随机推荐

  1. 在ReactNative中使用Typescript

    在ReactNative中使用Typescript 少侠放心,跟着我的这个步骤走,保你完美在RN项目中使用Typescript,废话不多说,走你 1.全局安装create-react-native-a ...

  2. HTML5+ MUI实现ajax的一个demo

    index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> &l ...

  3. 基于pygame的打砖块游戏,做到一半,不带做了

    跟着一个博主做的,前面的变量的定义全是内个哥们的,没带任何改动,就做了个界面,背景音乐,绘制了个小球,绘制了挡板 小球可以撞到边界反弹,然后做了砖块,定义了一个存放砖块的列表,,,就没有下文了 原博主 ...

  4. centos7上部署新版 jumpserver 跳板机服务

    CentOS 7 建议在一个纯净的 centos7上进行下面的安装部署 关闭 selinux 和防火墙 [root@jumpserver ~]# setenforce 0 [root@jumpserv ...

  5. Linux Shell 与Linux常用命令

    Linux的人际交互分为图形界面方式和命令行方式. Linux本身只是一个操作系统内核,而由X Window图形用户接口为Linux提供图形用户界面功能.可以把X Window理解为一个运行在Linu ...

  6. array_x

    import java.util.*; public class array_x { public static void main(String args[]) { int a[][]={{2,4, ...

  7. [转载]三小时学会Kubernetes:容器编排详细指南

    原翻译by梁晓勇 原英文:Learn Kubernetes in Under 3 Hours: A Detailed Guide to Orchestrating Containers 我很奇怪,为什 ...

  8. UVA 1593 Alignment of Code(紫书习题5-1 字符串流)

    You are working in a team that writes Incredibly Customizable Programming Codewriter (ICPC) which is ...

  9. Spring 中的文件上传与下载控制

    先创建根应用上下文配置,WebDemo/src/main/java/com/seliote/webdemo/config/RootContextConfig.java package com.seli ...

  10. Zookeeper系列(二) Zookeeper配置说明

            在配置ZooKeeper配置文件时,有些参数是必需的,有些参数是可选的,这些必需的参数构成了Zookeeper配置文件的最低配置要求,如果需要对ZooKeeper进行更详细的配置,可以 ...