HDOJ 1160 FatMouse's Speed (子序列 - 动态规划)

题目:

FatMouse's Speed

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5546    Accepted Submission(s): 2393
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
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1160
 

题意:

要求找到的体重递增,速度递减的老鼠,并且输出最长的长度数,而且输出各自的序列数。(Special Judge  说明答案不唯一,只要输出的答案正确就可以)

 

思路:

题目要求找到的体重递增,速度递减的老鼠,先把老鼠的体重进行升序排序,然后算出所给的数据序列的最长值,记录最长的序列要用father值来记录,path值则是来记录路径的,这两个是最重要的,另外还有注意题目是要求输入是以文件结束的,所以输入要想下面那样写,下面为图解(图的作用就是解释一下father和path的用法):

代码:(这是别人的代码,写得比较好,而且注释比较详细,所以就copy下来的)

/*
	
	老鼠跑步题 FatMouse's Speed 
	老鼠的体重和速度满足 体重越重,速度越慢 的最长序列
	
	题解:
		  对最长递增子序列的一个变形,要将两个决定元素转换为一个,所以先对老鼠
		  
			的体重从小到大排好序再对速度来求最长递减序列,反之也可。

	状态转移方程:

		max(  max(mouse[j].sp  |  j mouse[j].fa && mouse[i].sp
#include
#include
using namespace std;


#define Max  150000


//动态规划的 打表数组 ; father[k]定义为:第k只老鼠排在子序列的第几位;
int father[Max];


//记录路径  path[k]定义为:第k只老鼠所在子序列的前一个满足要求的老鼠是;
int path[Max];  


//排序后老鼠序列和数组下标会有变化,注意index的理解和使用====记录path路径时候;
struct Node{

	int fa;
	int sp;
	int index; //记录是第几只老鼠  输入时的次序
	const bool operator < ( const Node old ) const{

		return fa>fat>>spe){
		mouse[n].fa=fat;
		mouse[n].sp=spe;
		mouse[n].index=n;
		n++;
	}

	//按体重排序;
	sort(mouse+1,mouse+n);

	int index(0);   //记录最大子序列的最后一个元素
	int max(-12122); //记录当前最
	int cut(0); 

	//初始化时所有的老鼠的路径只有自己,
	for(int kp(0);kp<=n;kp++){
		path[kp]=kp;
	}

	for(int i(1); i mouse[j].fa && mouse[i].sp < mouse[j].sp  &&  father[i]max ){
					max= father[i];
					index= i;
				}

			}
		}

	}
	cout< st;

	//获得子序列,--对应最短路径的输出路径 ---反向存储,用栈保存
	while(  path[index]!=index){
		st.push(mouse[index].index);
		index=path[index];
	}
	st.push(mouse[index].index);

	while( !st.empty()){
		cout<


 

你可能感兴趣的:(动态规划)