HDU 1160 FatMouse's Speed【C++练习题】

FatMouse’s Speed
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 22143 Accepted Submission(s): 9847
Special Judge

Problem Description

FatMouse believes that the fatter a mouse is, the faster it runs. To disprove this, you want to take the data on a collection of mice and put as large a subset of this data as possible into a sequence so that the weights are increasing, but the speeds are decreasing.

Input

Input contains data for a bunch of mice, one mouse per line, terminated by end of file.

The data for a particular mouse will consist of a pair of integers: the first representing its size in grams and the second representing its speed in centimeters per second. Both integers are between 1 and 10000. The data in each test case will contain information for at most 1000 mice.

Two mice may have the same weight, the same speed, or even the same weight and speed.

Output

Your program should output a sequence of lines of data; the first line should contain a number n; the remaining n lines should each contain a single positive integer (each one representing a mouse). If these n integers are m[1], m[2],…, m[n] then it must be the case that

W[m[1]] < W[m[2]] < … < W[m[n]]

and

S[m[1]] > S[m[2]] > … > S[m[n]]

In order for the answer to be correct, n should be as large as possible.
All inequalities are strict: weights must be strictly increasing, and speeds must be strictly decreasing. There may be many correct outputs for a given input, your program only needs to find one.

Sample Input

6008 1300
6000 2100
500 2000
1000 4000
1100 3000
6000 2000
8000 1400
6000 1200
2000 1900

Sample Output

4
4
5
9
7

Source

Zhejiang University Training Contest 2001

Recommend

Ignatius

问题简述:
题目大意是找到一个最多的老鼠序列,使得序列中的老鼠的体重满足递增,相应老鼠的速度满足递减。思路就是先按体重递增进行sort排序,然后按照体重找到最长递减子序列即可,用动态规划做比较简单。状态f[i]表示前i个老鼠中的最长递减子序列长度, 最后找出最大的f[i]即可。注意此题还需要输出找到的序列中的老鼠的最原始的标号,因此不仅要在刚开始的时候把每个老鼠的最初的序号记下来,还要在进行状态转移的时候把当前的老鼠的位置标记下来。

贴上代码↓↓↓

#include<iostream>
#include<algorithm>
using namespace std;

struct node
{
	int w;
	int s;
	int no;
}mice[1005];

struct node2
{
	int sum=1;
	int pre=0;
}dp[1005];
bool cmp(node a, node b)
{
	if (a.w == b.w)
		return a.s > b.s;
	return a.w < b.w;
}

void main()
{
	int k = 0, max, t;
	while (cin>>mice[k].w>>mice[k].s &&mice[k].w&&mice[k].s)
	{
		mice[k].no = k + 1;
		k++;
	}
	sort(mice, mice + k, cmp);
	max = 1;
	t = 1;
	for (int i = 1; i < k; i++)
	{
		for (int j = 0; j < i; j++)
		{
			if (mice[j].s > mice[i].s&&mice[j].w < mice[i].w)//找出质量大速度小的
			{
				if (dp[i].sum < dp[j].sum + 1)//最大连续序列
				{
					dp[i].sum = dp[j].sum + 1;
					dp[i].pre = j;
				}
			}
		}
		if (dp[i].sum > max)
		{
			max = dp[i].sum;
			t = i;
		}
	}
	cout << max << endl;
	int m[1005];
	for (int i = 1; i <= max; i++)
	{
		m[i] = t;
		t = dp[t].pre;
	}
	for (int j = max; j >= 1; j--)
		cout<<mice[m[j]].no<<endl;
}
### HDU 4393 抛钉子 C++ 实现与算法思路 #### 算法分析 针对 HDU 4393 的问题,可以采用三种不同的方法来解决问题。以下是每种方法的具体描述及其背后的逻辑。 1. **基于时间分段的排序策略** 如果考虑 `Fi` 最大值为 500,则在超过 501 秒的时间范围内,速度 `Si` 将成为决定排名的主要因素。因此,在此时间段内,可以通过简单的排序操作完成最终排名计算[^2]。具体而言: - 在前 501 秒内通过暴力方式逐一模拟每个选手的状态变化。 - 排序依据:当 `t >= 501` 时,若两个选手的 `Fi` 相同,则比较其 ID;否则仅需关注 `Si` 即可得出最终排名。 2. **利用二维单调性优化搜索过程** 若路径长度 `way` 和速度 `speed` 构成了一组二维不递增序列,则该条件下各选手之间的相对位置关系保持不变。这意味着一旦发现某时刻满足上述特性,后续无需再继续更新状态而可以直接输出当前结果。这种方法减少了不必要的迭代次数从而提高了效率。 3. **优先队列辅助下的动态规划方案** 鉴于题目设定中提到的最大初始力量值不超过 100 (`S_i ≤ 100`) ,我们能够构建一系列大小固定的小型优先队列用于管理不同类别下可能获胜者的信息集合。这些小型优先队列分别存储具有特定初速等级的所有参赛人员数据,并按照各自的第一关键属性即剩余力场强度以及次级区分标准如编号来进行排列整理工作流程如下所示: - 初始化阶段创建若干个独立运作但相互关联紧密程度较高的专用容器结构体实例对象; - 每轮循环期间从各个活跃中的候选池子里挑选出符合条件的最佳选项加以处理直至结束为止。 #### 示例代码实现 (Method One) 下面提供了一个基于第一种解决方案编写而成的有效程序版本: ```cpp #include <bits/stdc++.h> using namespace std; struct Player { int id; int f; // force int s; // speed }; bool cmp(const Player &a, const Player &b){ if(a.f != b.f) return a.f > b.f; else return a.id < b.id; } int main(){ ios::sync_with_stdio(false); cin.tie(0); int T; cin >> T; while(T--){ int n,t; cin>>n>>t; vector<Player> players(n); for(int i=0;i<n;++i){ players[i].id=i+1; cin>>players[i].f>>players[i].s; } if(t<=501){ sort(players.begin(), players.end(), [&](const Player& p1,const Player& p2)->bool{ long long w1=(long long)p1.s*(t-1)+p1.f; long long w2=(long long)p2.s*(t-1)+p2.f; if(w1!=w2)return w1>w2; else return p1.id<p2.id; }); } else{ // t>501 sort(players.begin(), players.end(),cmp); } for(auto &player : players){ cout<<player.id<<" "; } cout<<"\n"; } } ``` #### 结论 以上介绍了三种适用于解决 HDU 4393 “Throw Nails” 问题的不同技术手段及其相应的理论基础说明文档内容摘录自参考资料部分所提及之处^。开发者可以根据实际需求选择最适合自己的那一款进行编码实践测试验证效果如何!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值