一开始想的贪心,可是发现贪心的问题太多了啊!只能保证当前最优,全局完全无法考虑。

所以正解是dp。预处理出前缀和,枚举每个区间,在每个点记录$now[i]$表示以$i$这个塔结尾的塔组目前的高度。$dp[i]$表示以$i$这个塔结尾最多能分成多少组。如果$dp[i]$可以更新成更优值,则直接更新$dp$和$now$值,否则如果$dp$值相同,则尽量使$now$值最小。

#include<iostream>
#include<cstdio>
#define ll long long
using namespace std; ll n, h[], pre[], now[], dp[]; int main ( ) {
freopen ( "tower.in", "r", stdin );
freopen ( "tower.out", "w", stdout );
scanf ( "%I64d", &n );
for ( int i = ; i <= n; i ++ )
scanf ( "%I64d", &h[i] ), pre[i] = pre[i-] + h[i];
for ( int i = ; i <= n; i ++ )
for ( int j = ; j < i; j ++ ) {
if ( pre[i] - pre[j] >= now[j] ) {
if ( dp[i] < dp[j] + ) dp[i] = dp[j] + , now[i] = pre[i] - pre[j];
else if ( dp[i] == dp[j] + ) {
now[i] = min ( now[i], pre[i] - pre[j] );
}
}
}
printf ( "%I64d", n - dp[n] );
return ;
}

显然(?)也是dp,$dp[i][j]$表示完成了$i$天,此时能力值为$j$时能做的最多工作量。$fine[i]$是预处理出的能力值为$i$时的效率最高的工作需要的时间。$qwq[i][j]$表示每个上完课后的第1天$i$,能力值为$j$,上课最短的时间。$pre[i]$表示过了$i$天可以得到的最大$dp$值。

枚举天数,能力值。

每次更新时可以选择不作为,即$dp[i][j]$直接从$dp[i-1][j]$转移过来。

如果第$i$天是某次刚上完课的第二天,则可以选择上课,从上课开始之前的最优$dp$值转移过来,即上课开始那一天的$pre$值。

如果当前天数和$fine[j]$满足可以工作,则从不工作那天转移过来,可以选择工作一次。

【注意】$dp$值初始化是负无穷,保证如果第$i$天不能满足$j$的能力值,则一定不会被更新,或去更新$pre$值。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define RG register
using namespace std; int T, S, N, fine[], qwq[][], pre[], dp[][]; struct LRN {
int m, l, a;
} stdy[]; int main ( ) {
freopen ( "wrk.in", "r", stdin );
freopen ( "wrk.out", "w", stdout );
scanf ( "%d%d%d", &T, &S, &N );
memset ( qwq, 0x3f3f3f3f, sizeof ( qwq ) );
for ( RG int i = ; i <= S; i ++ ) {
int m, l, a;
scanf ( "%d%d%d", &m, &l, &a );
qwq[l+m][a] = min ( qwq[l+m][a], l );
}
memset ( fine, 0x3f3f3f3f, sizeof ( fine ) );
for ( RG int i = ; i <= N; i ++ ) {
int c, d;
scanf ( "%d%d", &c, &d );
fine[c] = min ( fine[c], d );
}
for ( int i = ; i <= ; i ++ )
fine[i] = min ( fine[i], fine[i-] );
memset ( dp, -0x3f3f3f3f, sizeof ( dp ) );
dp[][] = ;
for ( int i = ; i <= T; i ++ ) {
for ( int j = ; j <= ; j ++ ) {
dp[i][j] = dp[i-][j];
if ( qwq[i][j] != 0x3f3f3f3f ) dp[i][j] = max ( dp[i][j], pre[i-qwq[i][j]] );
if ( i - fine[j] >= ) dp[i][j] = max ( dp[i][j], dp[i-fine[j]][j] + );
pre[i] = max ( dp[i][j], pre[i] );
}
}
printf ( "%d", pre[T] );
return ;
}

很有趣的一道题。题目给出的性质是只有一个点的度数大于等于3,先找出这个点作为root。

bfs预处理出点距离的邻接矩阵,二分答案,每次去check的时候是选择root周围可以覆盖它的点,割掉这个点去更新答案。设当前枚举的点是$x$,先标记$x$可以覆盖的所有点,再dfs去计算没有被标记的点的数量,就是被拆分开的一条条链上的点的数量,每条链上需要的树洞是$ceil ( \frac{1.0 * now}{2*len+1} )$,$now$是这条链上的点数,注意因为自己也会算进去,所以一个点能覆盖的点数是$2*len+1$。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std; int n, m, k, root;
int dis[][], d[]; int stot, tov[], nex[], h[];
void add ( int u, int v ) {
tov[++stot] = v;
nex[stot] = h[u];
h[u] = stot;
} queue < int > q;
void bfs ( int s ) {
queue < int > q; q.push ( s );
while ( !q.empty ( ) ) {
int x = q.front ( ); q.pop ( );
for ( int i = h[x]; i; i = nex[i] ) {
int v = tov[i]; d[x] ++; d[v] ++;
if ( !dis[s][v] && v != s )
dis[s][v] = dis[s][x] + , q.push ( v );
}
}
} int now, v[]; void dfs ( int u ) {
now += ( v[u] = );
for ( int i = h[u]; i; i = nex[i] )
if ( !v[tov[i]] )
dfs ( tov[i] );
} int work ( int x, int len ) {
int s = ;
memset ( v, , sizeof ( v ) );
for ( int i = ; i <= n; i ++ )
v[i] = ( dis[i][x] <= len );
for ( int i = ; i <= n; i ++ )
if ( !v[i] ) now = , dfs ( i ), s += ceil ( 1.0 * now / ( * len + ) );
return s;
} bool check ( int x ) {
int ans = 0x3f3f3f3f;
for ( int i = ; i <= n; i ++ )
if ( dis[root][i] <= x ) {
ans = min ( ans, work ( i, x ) );
}
return ans < k;
} int main ( ) {
freopen ( "holes.in", "r", stdin );
freopen ( "holes.out", "w", stdout );
scanf ( "%d%d%d", &n, &m, &k );
for ( int i = ; i <= m; i ++ ) {
int x, y;
scanf ( "%d%d", &x, &y );
add ( x, y ); add ( y, x );
}
for ( int i = ; i <= n; i ++ ) {
bfs ( i );
if ( d[i] > ) root = i;
}
if ( !root ) {
cout << ceil ( 1.0 * ( n - k ) / ( k << ) );
return ;
}
int l = , r = n, ans;
while ( l <= r ) {
int mid = ( l + r ) >> ;
if ( check ( mid ) ) r = mid - , ans = mid;
else l = mid + ;
}
cout << ans;
return ;
}

【8.20校内测试】【DP】【二分+贪心】的更多相关文章

  1. 【8.23校内测试】【贪心】【线段树优化DP】

    $m$的数据范围看起来非常有问题??仔细多列几个例子可以发现,在$m<=5$的时候,只要找到有两行状态按位$&$起来等于$0$,就是可行方案,如果没有就不行. #include<i ...

  2. 2019.6.20 校内测试 NOIP模拟 Day 1 分析+题解

    这次是zay神仙给我们出的NOIP模拟题,不得不说好难啊QwQ,又倒数了~ T1 大美江湖 这个题是一个简单的模拟题.   ----zay 唯一的坑点就是打怪的时候计算向上取整时,如果用ceil函数一 ...

  3. 【8.30校内测试】【找规律模拟】【DP】【二分+贪心】

    对于和规律或者数学有关的题真的束手无策啊QAQ 首先发现两个性质: 1.不管中间怎么碰撞,所有蚂蚁的相对位置不会改变,即后面的蚂蚁不会超过前面的蚂蚁或者落后更后面的蚂蚁. 2.因为所有蚂蚁速度一样,不 ...

  4. 两种解法-树形dp+二分+单调队列(或RMQ)-hdu-4123-Bob’s Race

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4123 题目大意: 给一棵树,n个节点,每条边有个权值,从每个点i出发有个不经过自己走过的点的最远距离 ...

  5. 【bzoj3312】[Usaco2013 Nov]No Change 状态压缩dp+二分

    题目描述 Farmer John is at the market to purchase supplies for his farm. He has in his pocket K coins (1 ...

  6. HDU-3681-Prison Break(BFS+状压DP+二分)

    Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But one da ...

  7. 1. 线性DP 887. 鸡蛋掉落 (DP+二分)

    887. 鸡蛋掉落 (DP+二分) https://leetcode-cn.com/problems/super-egg-drop/ /*首先分析1个蛋,1个蛋的话,最坏情况需要N次,每次只能从0 1 ...

  8. HDU 3433 (DP + 二分) A Task Process

    题意: 有n个员工,每个员工完成一件A任务和一件B任务的时间给出,问要完成x件A任务y件B任务所需的最短时间是多少 思路: DP + 二分我也是第一次见到,这个我只能说太难想了,根本想不到. dp[i ...

  9. Codeforces Gym 100231B Intervals 线段树+二分+贪心

    Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...

随机推荐

  1. 去除IE10+上文本框巨丑无比的删除图标以及显示密码图标

    去除IE10+上文本框巨丑无比的删除图标以及显示密码图标 IE浏览器总是让人喜欢让人厌,在最新的IE浏览器(IE10+)上使用表单时,文本框内后面会出现很巨丑无比的“删除图标”以及“显示密码图标”,如 ...

  2. JS日历控件特效代码layDate

    https://www.js-css.cn/a/jscode/date/2015/0405/1461.html

  3. password passphrase passcode 的区别

    In general, passphrases are long passwords and passcodes are numeric-only passwords.

  4. ubuntu sougou输入法

    1, 打开搜狗输入法Linux版的官网http://pinyin.sogou.com/linux/?r=pinyin,并下载你需要的版本,这里选择64位版. 2,在Ubuntu14.01下可以直接点击 ...

  5. elk系列1之入门安装与基本操作【转】

    preface 我们每天都要查看服务器的日志,一方面是为了开发的同事翻找日志,另一方面是巡检服务器查看日志,而随着服务器数量以及越来越多的业务上线,日志越来越多,人肉运维相当痛苦了,此时,参考现在非常 ...

  6. 大数据系列之kafka监控kafkaoffsetmonitor安装

    1.下载kafkaoffsetmonitor的jar包,可以到github搜索kafkaoffsetmonitor,第一个就是,里面可以下载编译好了的包. KafkaOffsetMonitor-ass ...

  7. eclipse maven jetty启动修改默认端口

    如何修改eclipse中的maven项目jetty服务器的默认端口那?网上有很多办法,但配置上都没有效果,最后找到了简单.简洁的解决办法,就是在eclipse的jetty启动命令后面加上以下内容 je ...

  8. nginx配置--event模块

    在nginx的配置中,event模块可以进行以下配置: 设置网络连接的序列化. 在Nginx服务器的多进程下,有可能出现惊群(Thundering herd problem)问题,指的是当某一个时刻只 ...

  9. linux抓包工具tcpdump基本使用

    tcpdump 是一款灵活.功能强大的抓包工具,能有效地帮助排查网络故障问题. tcpdump 是一个命令行实用工具,允许你抓取和分析经过系统的流量数据包.它通常被用作于网络故障分析工具以及安全工具. ...

  10. MVC – 14.ajax异步请求

    14.1.配置文件 14.2.AjaxHelper – 异步链接按钮 14.3.AjaxHelper – 异步表单 AjaxOptions常见属性: 14.4.AjaxOptions对象生成[对应]触 ...