cdoj 1351 柱爷抢银行III

柱爷抢银行III
Time Limit: 1000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)

若干年后,柱爷再次来到了喵蛤蛤城,准备再干一票!!
这一次,喵蛤蛤城早已不是之前的样子,喵哈哈城里有N个银行,用N−1条双向马路相连,银行的编号为0,1,2,......,N−1,任意的两个银行间接或直接都能相互到达.
第i条马路会有一个权值di,表示柱爷经过这条马路需要花费的精力值,从马路的任意一端出发,这个权值保持不变.
柱爷决定从这些银行中抢一部分银行,只要柱爷的精力值非负,柱爷就能洗劫所在点的银行;当然因为柱爷抢银行抢的特别熟练,所以柱爷抢银行是不需要花费精力值的.
柱爷到达了0号银行,在洗劫0号前,柱爷突然想知道一个问题:如果我有x点精力值,我能抢劫几个银行呢.
你能帮柱爷解决这抢劫的小小问题吗?

Input

第一行,一个正整数:N表示银行个数.
接下去N−1N−1行,每行一个3个非负整数:u,v,d表示第u号银行和第v号银行之间有一条需要花费d精力值的马路.
接下去一个非负整数:q表示柱爷共有q个问题.
接下去有q行,每行有一个非负整数:x表示这次柱爷设想自己有x的精力值.



数据保证:

1≤N≤500
1≤di≤10000
0≤u,v<N
1≤q≤1000
0≤x≤5000000

Output
输出一共有q行,每行一个整数:ans表示柱爷第q次设想时最多可以抢的银行数目.

Sample Input
3
1 0 5
2 0 3
4
2
3
10
11
Sample Output
1
2
2
3
Source

2016 UESTC Training for Dynamic Programming

题解

此题很明显是一个树形dp,由于x很小,我们定义dp[u][k]表示在u节点走k个节点的最小花费。发现无法转移,我们就再添一维表示是否在u节点。

#include <bits/stdc++.h>
using namespace std;

const int Maxn = 503;
typedef pair<int,int> pii;
vector<pii>edge[Maxn];
int dp[Maxn][Maxn][2];

void SelfMin(int &a, const int &b) { if (b < a) a = b; }

int Cal(int u, int fa) {
	int siz = 1, v, d, sons; dp[u][1][1] = 0;
	for (int i = 0; i < edge[u].size(); ++i) {
		v = edge[u][i].first, d = edge[u][i].second;
		if (v == fa) continue;
		sons = Cal(v, u);
		for (int j = siz; j; --j)
			for (int k = sons; k; --k) {
				SelfMin(dp[u][j + k][0], dp[u][j][0] + dp[v][k][1] + (d << 1));
				SelfMin(dp[u][j + k][0], dp[u][j][1] + dp[v][k][0] + d);
				SelfMin(dp[u][j + k][0], dp[u][j][1] + dp[v][k][1] + d);
				SelfMin(dp[u][j + k][1], dp[u][j][1] + dp[v][k][1] + (d << 1));
			}
		siz += sons;
	}
	return siz;
}

int main() {
	int N, u, v, d, Q;
	scanf("%d", &N);
	memset(dp, 127, sizeof dp);
	for (int i = 1; i < N; ++i) {
		scanf("%d%d%d", &u, &v, &d);
		edge[u].push_back(make_pair(v, d));
		edge[v].push_back(make_pair(u, d));
	}
	Cal(0, -1);
	scanf("%d", &Q);
	while (Q--) {
		scanf("%d", &d);
		u = 0;
		while (dp[0][u + 1][0] <= d || dp[0][u + 1][1] <= d) ++u;
		printf("%d\n", u);
	}
	return 0;
}


代码下载地址: https://pan.quark.cn/s/b4a8e0160cfc 齿轮与轴系零件在机械设备中扮演着至关重要的角色,它们负责实现动力传输、调整运动形态以及承受工作载荷等核心功能。 在机械工程的设计实践中,齿轮和轴系的设计是一项关键的技术任务,其内容涵盖了材料选用、构造规划、承载能力分析等多个技术层面。 下面将系统性地介绍《齿轮及轴系零件结构设计指导书》中的核心知识点。 一、齿轮设计1. 齿轮种类:依据齿廓轮廓的不同,齿轮可划分为直齿齿轮、斜齿轮以及人字齿轮等类别,各类齿轮均具有特定的性能特点与适用工况,能够满足多样化的工作环境与载荷需求。 2. 齿轮规格参数:模数大小、压力角数值、齿数数量、分度圆尺寸等是齿轮设计的基础数据,这些参数直接决定了齿轮的物理尺寸与运行性能。 3. 齿轮材质选用:齿轮材料的确定需综合评估其耐磨损性能、硬度水平以及韧性表现,常用的材料包括铸铁、钢材、铝合金等。 4. 齿轮强度验证:需进行齿面接触应力分析与齿根弯曲应力分析,以确保齿轮在实际运行过程中不会出现过度磨损或结构破坏。 5. 齿轮加工工艺:涉及切削加工、滚齿加工、剃齿加工、淬火处理等工艺流程,工艺方案的选择将直接影响齿轮的加工精度与使用寿命。 二、轴设计1. 轴的分类方式:依据轴在机械装置中的功能定位与受力特点,可将轴划分为心轴、转轴以及传动轴等类型。 2. 轴的材料选择:通常采用钢材作为轴的材料,例如碳素结构钢或合金结构钢,特殊需求时可选用不锈钢材料或轻质合金材料。 3. 轴的构造规划:需详细考虑轴的轴向长度、截面直径、键槽布置、轴承安装位置等要素,以满足轴的强度要求、刚度要求以及稳定性要求。 4. 轴的强度验证:需进行轴的扭转强度分析与弯曲强度分析,以防止轴在运行过程中发生塑性变形...
### CDOJ 300 木杆上的蚂蚁 #### 题目描述 题目涉及若干只蚂蚁在一个长度为 \( L \) 的水平木杆上移动。每只蚂蚁初始位置和方向已知,当两只蚂蚁相遇时会立即掉头反向行走。目标是计算所有蚂蚁最终离开木杆的时间以及它们的顺序。 --- #### 解决方案概述 该问题的核心在于模拟蚂蚁的行为并处理碰撞事件。尽管表面上看起来需要复杂的碰撞检测逻辑,但实际上可以通过一种巧妙的方式简化问题:假设蚂蚁在碰撞时不改变方向,则可以忽略碰撞的影响[^2]。因此,只需关注每只蚂蚁到达木杆两端所需时间即可。 以下是解决问题的主要思路: 1. **输入解析** 输入数据包括测试用例数量 \( T \),每个测试用例包含木杆长度 \( L \) 和蚂蚁的数量 \( N \)。对于每只蚂蚁,记录其初始位置和移动方向(左或右)。 2. **时间和顺序计算** 对于每只蚂蚁: - 如果它朝左移动,则离木杆左侧的距离为其当前位置; - 如果它朝右移动,则离木杆右侧的距离为 \( L - \text{当前蚂蚁的位置} \)。 将这些距离存储下来,并按升序排列以确定蚂蚁离开木杆的顺序。 3. **输出结果** 输出每只蚂蚁离开木杆的时间及其编号。 --- #### Python 实现代码 以下是一个完整的 Python 实现: ```python t = int(input()) # 测试用例数量 for case in range(1, t + 1): n, l = map(int, input().split()) # 蚂蚁数量和木杆长度 ants = [] for _ in range(n): idx, pos, direction = input().split() idx = int(idx) pos = int(pos) if direction == 'L': time_to_fall = pos # 到达左边所需时间 else: time_to_fall = l - pos # 到达右边所需时间 ants.append((time_to_fall, idx)) # 按照掉落时间排序 sorted_ants_by_time = sorted(ants, key=lambda x: x[0]) # 提取原始索引以便后续匹配 original_indices = list(range(len(sorted_ants_by_time))) # 打印结果 print(f"Case #{case}:") for ant_index in original_indices: print(sorted_ants_by_time[ant_index][1], end=" ") print() ``` --- #### 关键点解释 1. **碰撞不影响总时间** 假设蚂蚁在碰撞时不改变方向,则整个过程中的最大时间为任意一只蚂蚁到最近端点的最大距离。这使得我们可以跳过复杂的状态更新操作[^2]。 2. **效率优化** 使用内置函数 `sorted` 可以高效完成排序任务,算法整体复杂度为 \( O(N \log N) \)。 3. **边界件** 特殊情况包括仅有一只蚂蚁的情况或者所有蚂蚁都朝同一方向移动的情形。程序应能正确处理此类场景。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值