目录

  • A : 直径数量问题
  • B : 城市规划
  • C : 最大区间和
  • D : 帝国大厦
  • 思路

A : 直径数量问题

题目描述
给出一棵树,求树的直径及其数量(最长简单路径的长度和数量)。

输入格式
第一行一个整数 nn , 0\le n\le10^50≤n≤10
5

接下来有 n-1n−1 行,每行 a,ba,b 代表 aa 到第 bb 有一条长度为 11 的边。
1\le a,b\le n1≤a,b≤n

输出格式
输出两个数,分别表示树的直径和数量。

样例输入
5
5 1
1 2
2 3
2 4
样例输出
3 2

#include<bits/stdc++.h>
#include<time.h>
#include <fstream>
#define forn(i,n) for(long long i=1;i<=n;i++)
const long long N = 1000100;
const long long mod = 1000000007;
using namespace std;
void in(long long &x){x=0;char c=getchar();long long y=1;while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+c-'0';c=getchar();}x*=y;
}
void o(long long x){if(x<0){x=-x;putchar('-');}if(x>9)o(x/10);putchar(x%10+'0');
}
long long n;
vector<long long> g[N];
class pa{public:long long len,cnt;void operator = (const pa &t){len=t.len,cnt=t.cnt;}bool operator < (const pa &t)const{return len*(long long)10000000+cnt<t.len*(long long)10000000+t.cnt;}pa(long long x,long long y):len(x),cnt(y){};pa(){len=1,cnt=1;}
};
pa dp1[N],dp2[N];
void dfs(long long u,long long fa){long long len1=0,len2=0;for(long long i=0;i<g[u].size();i++){long long v = g[u][i];if(v==fa)continue;dfs(v,u);if(dp1[u].len<dp1[v].len+1){dp1[u]=dp1[v];dp1[u].len++;}else if(dp1[u].len==dp1[v].len+1){dp1[u].cnt+=dp1[v].cnt;}if(dp1[v].len>len2)len2=dp1[v].len;if(len1<len2)swap(len1,len2);dp2[u]=max(dp2[u],dp1[u]);dp2[u]=max(dp2[u],dp2[v]);}if(len2==0)return;if(len1+len2+1>=dp2[u].len){if(len1+len2+1!=dp2[u].len)dp2[u].cnt=0;dp2[u].len=len1+len2+1;if(len1==len2){long long cnt = 0,sum = 0;for(long long i=0;i<g[u].size();i++){long long v= g[u][i];if(v==fa)continue;if(dp1[v].len==len1){sum+=dp1[v].cnt*cnt;cnt+=dp1[v].cnt;}}dp2[u].cnt+=sum;}else{long long cnt1=0,cnt2=0;for(long long i=0;i<g[u].size();i++){long long v= g[u][i];if(v==fa)continue;if(dp1[v].len==len1){cnt1=dp1[v].cnt;}else if(dp1[v].len==len2){cnt2+=dp1[v].cnt;}}dp2[u].cnt+=cnt1*cnt2;}}
}
signed main(){in(n);forn(i,n-1){long long x,y;in(x);in(y);g[x].push_back(y);g[y].push_back(x);}dfs(1,0);cout<<dp2[1].len-1<<" "<<dp2[1].cnt;return 0;
}

B : 城市规划

题目描述
有一座城市,城市中有 NN 个公交站,公交站之间通过 N-1N−1 条道路连接,每条道路有相应的长度。保证所有公交站两两之间能够通过唯一的通路互相达到。
两个公交站之间路径长度定义为两个公交站之间路径上所有边的边权和。
现在要对城市进行规划,将其中 MM 个公交站定为“重要的”。
现在想从中选出 KK 个节点,使得这 KK 个公交站两两之间路径长度总和最小。输出路径长度总和即可(节点编号从 11 开始)。

输入格式
第 11 行包含三个正整数 N, MN,M 和 KK 分别表示树的节点数,重要的节点数,需要选出的节点数。
第 22 行包含 MM 个正整数,表示 MM 个重要的节点的节点编号。
接下来 N-1N−1 行,每行包含三个正整数 a, b, ca,b,c,表示编号为 aa 的节点与编号为 bb 的节点之间有一条权值为 cc 的无向边。每行中相邻两个数之间用一个空格分隔。

输出格式
输出只有一行,包含一个整数表示路径长度总和的最小值。

样例输入
5 3 2
1 3 5
1 2 4
1 3 5
1 4 3
4 5 1
样例输出
4
样例解释

样例中的树如上图所示。
重要的节点标号为 1, 3, 5,从中选出两个点,有三种方案:
方案 1: 1, 3 之间路径长度为 5
方案 2: 1, 5 之间路径长度为 4
方案 3: 3, 5 之间路径长度为 9

数据规模与子任务

对于所有的数据,1≤a,b≤N,c≤10^5,M≤N,K≤M1≤a,b≤N,c≤10
5 ,M≤N,K≤M

#include<bits/stdc++.h>
#include<time.h>
#include <fstream>
#define forn(i,n) for(long long i=1;i<=n;i++)
const long long N = 50100;
const long long mod = 1000000007;
using namespace std;
void in(long long &x){x=0;char c=getchar();long long y=1;while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+c-'0';c=getchar();}x*=y;
}
void o(long long x){if(x<0){x=-x;putchar('-');}if(x>9)o(x/10);putchar(x%10+'0');
}
long long n,K,m;
long long dp[N][110];
long long numk[N];
bool k[N];
vector<long long>g[N];
vector<long long>g2[N];
long long ans = 0x3fffffffffffffff;
void dfs(long long u,long long fa){dp[u][0]=0;if(k[u])dp[u][1]=0,numk[u]=1;for(long long i=0;i<g[u].size();i++){long long v = g[u][i];if(v==fa)continue;dfs(v,u);numk[u]+=numk[v];numk[u]=min(numk[u],K);for(long long k2=numk[u];k2>=1;k2--){for(long long k1=1;k1<=numk[v];k1++){dp[u][k2]=min(dp[u][k2],dp[v][k1]+k1*(K-k1)*g2[u][i]+dp[u][k2-k1]);}}}ans = min(ans,dp[u][K]);
}
signed main(){in(n);in(m);in(K);forn(i,m){long long x;in(x);k[x]=true;}forn(i,n-1){long long x,y,z;in(x);in(y);in(z);g[x].push_back(y);g[y].push_back(x);g2[x].push_back(z);g2[y].push_back(z);}memset(dp,0x3f,sizeof(dp));dfs(1,0);o(ans);return 0;
}

C : 最大区间和

题目描述
输入一个长度为 nn 的整数序列 aa,从中找出一段不超过 mm 的连续子序列(区间),使得这个序列的和最大。选出的区间可以为空。
n\le 10^6, m\le n, -10^9\le a_i\le 10^9n≤10
6 ,m≤n,−10 9 ≤a i ≤10 9

输入描述
第一行两个数 n,mn,m,第二行 nn 个整数 a_ia
i

表示这个数列。

输出描述
一个整数表示答案。

样例输入
6 3
1 -3 5 1 -2 3
样例输出
6

#include<bits/stdc++.h>
#include<time.h>
#define forn(i,n) for(ll i=1;i<=n;i++)
#define ll long long
using namespace std;
void in(ll &x){x=0;char c=getchar();ll y=1;while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+c-'0';c=getchar();}x*=y;
}
void o(ll x){if(x<0){x=-x;putchar('-');}if(x>9)o(x/10);putchar(x%10+'0');
}
ll n,m;ll ans=0;
ll sum[1000010],a[1000010];
deque <ll> p;
signed main(){in(n);in(m);for(ll i=1;i<=n;i++) {in(a[i]);sum[i]=sum[i-1]+a[i];}p.push_back(0);for(ll i=1;i<=n;i++){while(!p.empty()&&sum[p.back()]>sum[i])  p.pop_back();              //维护递增p.push_back(i);while(!p.empty()&&i-m>p.front()) p.pop_front();ans=max(ans,sum[i]-sum[p.front()]);}o(ans);return 0;
}

D : 帝国大厦

题目描述
帝国大厦共有 nn 层,LZH 初始时在第 aa 层上。
帝国大厦有一个秘密实验室,在第 bb 层,这个实验室非常特别,对 LZH 具有约束作用,即若 LZH 当前处于 xx 层,当他下一步想到达 yy 层时,必须满足 |x-y|<|x-b|∣x−y∣<∣x−b∣,而且由于实验室是不对外开放的,电梯无法停留在第 bb 层。
LZH 想做一次旅行,即他想按 kk 次电梯,他想知道不同的旅行方案个数有多少个。
两个旅行方案不同当前仅当存在某一次按下电梯后停留的楼层不同。

输入格式
一行 44 个数 n,a,b,kn,a,b,k。

输出格式
一个数表示答案,由于答案较大,将答案对 10^9+710
9
+7 取模后输出。

数据范围与子任务
对于 40%40% 的数据 n,k\le 500n,k≤500。
对于 80%80% 的数据 n,k\le 2000n,k≤2000。
对于 100%100% 的数据 n,k\le 5000, 1 \le a,b \le n, a\neq bn,k≤5000,1≤a,b≤n,a


=b。

Case 1
Input
5 2 4 1
Output
2
Case 2
Input
5 2 4 2
Output
2
Case 3
Input
5 3 4 1
Output
0

#include<bits/stdc++.h>
using namespace std;
const long long N = 5010;
const long long mod = 1000000007;
void in(long long &x){x=0;char c=getchar();long long y=1;while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+c-'0';c=getchar();}x*=y;
}
void o(long long x){if(x<0){x=-x;putchar('-');}if(x>9)o(x/10);putchar(x%10+'0');
}
long long n,aa,b,k;
long long pre[N];
long long a[2][N];
signed main(){in(n);in(aa);in(b);in(k);if(k==0){puts("0");return 0;}a[k&1][aa]=1;for(long long i=aa;i<=n;i++)pre[i]=1;while(k--){for(long long i=1;i<=n;i++){if(i>b){long long l = (i+b)/2;a[k&1][i]=pre[n]-pre[l];}else if(i<b){long long r = (i+b-1)/2+1;a[k&1][i]=pre[r-1]-pre[0];}a[k&1][i]-=a[(k+1)&1][i];a[k&1][i]+=mod;a[k&1][i]%=mod;}for(long long i=0;i<=n;i++){pre[i]=a[k&1][i];pre[i]+=pre[i-1];pre[i]%=mod;}}long long ans = 0;for(long long i=1;i<=n;i++){ans += a[0][i];ans%=mod;}o(ans);return 0;
}

思路



两次遍历就可以求出来树的直径



一个数组,让你求从一个从i到j和最大的这么一个范围
策略是:每输入第i个数要去判断要不要把这个数加入我前面所组成的数组x[i-1]里, 如果加入这个数后得到和不小于这个数,那就把这个数加入前面的数列,否则重新开始构建最大和的数列。 用两个数组x[i]存max(x[i]+a,a),x1[i]存处理每一个数时开始的位置

Week14-动态规划(四)相关推荐

  1. 【数据结构与算法】【算法思想】【联系与区别】回溯 贪心 动态规划 分治

    4种算法思想比较与联系 如果将贪心,分治,回溯和动态规划四种算法思想分类,那贪心,回溯,动态规划可归为一类,而分治单独可以作为一类,因为它跟其他是三个都不大一样. 因为前三个算法解决问题的模型,都可以 ...

  2. 动态规划(Dynamic Programming, DP)简介

    动态规划(Dynamic programming,DP)是一种在数学.计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法. 动态规划常常适用于有重叠子问题和最优子结 ...

  3. 【Python自然语言处理】读书笔记:第四章:编写结构化程序

    4 编写结构化程序 4.1 回到基础 1.赋值: 列表赋值是"引用",改变其中一个,其他都会改变 foo = ["1", "2"] bar ...

  4. 【动态规划】 最简入门教程

    看了本文还入不了门,那就基本告别动态规划了 : ) ~ 一.简介 二.[能用]动态规划解决的问题 三.[适合用]动态规划解决的问题 四.动态规划求解的3个关键步骤 1. 建立状态转移方程 2. 缓存小 ...

  5. 【数据结构与算法】【算法思想】贪心算法

    贪心算法 回溯算法 分治算法 动态规划 四种基本的算法思想:贪心算法,分治算法,回溯算法,动态规划,他们不是具体算法,常用来指导我们设计具体的算法和编码等. 一:贪心算法有很多经典应用 霍夫曼编码(H ...

  6. ApacheCN 深度学习译文集 20201229 更新

    新增了七个教程: TensorFlow 和 Keras 应用开发入门 零.前言 一.神经网络和深度学习简介 二.模型架构 三.模型评估和优化 四.产品化 TensorFlow 图像深度学习实用指南 零 ...

  7. 数据结构学习笔记(转载)

    数据结构笔记(1) 第一章 概  论 1.数据:信息的载体,能被计算机识别.存储和加工处理. 2.数据元素:数据的基本单位,可由若干个数据项组成,数据项是具有独立含义的最小标识单位. 3.数据结构:数 ...

  8. Python自然语言处理 | 编写结构化程序

    本章解决问题 怎么能写出结构良好.可读的程序,你和其他人将能够很容易的重新使用它? 基本结构块,如循环.函数以及赋值,是如何执行的? Python 编程的陷阱有哪些,你怎么能避免它们吗? 这里写目录标 ...

  9. 蓝桥杯python组一个星期备战记录贴

    蓝桥杯python组一个星期备赛记录贴 文章目录 前言 注意事项: 一.贪心算法 二.最小生成树之Prim算法 三.动态规划 四.递归算法 五.树与堆 前言 目前是2021年4月11日,一位pytho ...

  10. 100-数据结构与算法(下篇)

    现在我们续写上一章博客的内容(即99章博客的内容) 快速排序: 同冒泡排序一样,快速排序也属于交换排序,通过元素之间的比较和交换位置来达到排序的目的 不同的是,冒泡排序在每一轮中只把1个元素冒泡到数列 ...

最新文章

  1. Nat. Biotech.|药物设计的AI生成模型
  2. 张首晟生前重磅演讲:要用第一性原理的思维方式来理解今天的世界
  3. 提携数学天才陶哲轩的伯乐是谁?
  4. MongoDB 3.0+访问数据库的方法
  5. Swift基础一(代码)
  6. 说说IUnitOfWork~DbContext对象的创建应该向BLL层公开
  7. 手机归属地查询 API 接口
  8. Vue移动端 手机六位数密码框
  9. java链接Kepserver报错误码[0x8001FFFF]
  10. npm install 报警告npm WARN
  11. ECU Bootloader自学笔记
  12. BigSur下Safari14.1.1安装油猴插件(Tampermonkey)
  13. 阿里滑块x82y,223,224,225算法挺难的,千辛万苦。
  14. 【ESD专题】ESD和EOS有什么差异?
  15. 与airpods媲美的无线耳机推荐
  16. css如何让多个div并排显示
  17. 网页翻译软件-网页自动采集翻译软件免费
  18. Appium [Error: Could not detect Mac OS X Version from sw_vers output: '10.13.5 ']
  19. CTreeCtrl 详解
  20. 百分号编码和汉字的转换

热门文章

  1. 时间同步ntpdate
  2. 一篇感情真挚的HR活动稿
  3. Linux lsof命令详解
  4. OpenCvSharp (C# OpenCV) 实现扫描文本矫正应用与实现详解(附源码)
  5. java标签库 taglib pdf格式_JSP系列教材 (十)- JSTL Java Standard Tag Library 标准标签库...
  6. go mysql transfer_部署运行 · go-mysql-transfer产品手册 · 看云
  7. ClassIn下一代在线互动教室平台
  8. 动态更改日历图标launcher3
  9. DHCP和静态和服务器分别是什么?
  10. 蓝桥练习题(C++)——门派制作