hdu 1160 FatMouse's Speed

来源:互联网 发布:cmd mysql启动命令行 编辑:程序博客网 时间:2024/05/18 03:33

FatMouse's Speed

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7217    Accepted Submission(s): 3184
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 13006000 2100500 20001000 40001100 30006000 20008000 14006000 12002000 1900
 


 

Sample Output
44597

 

这道DP题的意思说,寻找一个 重量 递增 速度 递减 的最长子序列。并输出子序列中的一种

 

首先sort排序,首先按w递增排序,其次按速度s递减排序。

 

现在 就讲问题转化为 在速度s中寻找一个最长递减子序列 (重量也不能相等。。附加一个条件)

 

所以 每只老鼠当前的最长序列的长度 存储在v变量中。

第一只老鼠初始化v=1;

随后,每添加一直老鼠,就寻找当前 重量大于这只老鼠 速度小于这只老鼠 同时 当前序列最长的一只老鼠,如果寻找到 则这只老鼠的dp的v 等于当前找到老鼠的v+1

否则 作为一个新的序列起点 就是1 同时每次循环都检查 当前的最长子序列的长度并记录

 

因为这道题还要输出一个最优子序列  所以 还添加了 许多变量来记录他们  比如 q  opt  t 等等 很多变量  写的时候都是后加了  为了思路清晰点   但是还是很麻烦。。orz 

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

typedef struct a
{
 int w;//weight
 int s;//速度

 int v;//dp
 int num;//老鼠的编号

 int q;//DP过程中 他的最优解的上一个节点下标(sort后的)
}p;

p  aa[1010];
int opt[1010];

bool cmp(p a,p b)
{
 if(a.w!=b.w)  return a.w<b.w;
 return  a.s>b.s;//按照体重升序 其次按照速度降序
}

int main()
{
 int n;
 n=0;
 while(scanf("%d %d",&aa[n].w,&aa[n].s)!=EOF)
 {
  aa[n].num=n;
  n++;
 }
 //有N只老鼠
 sort(aa,aa+n,cmp);
 //寻找速度s的最长递减子序列
 aa[0].v=1;
 aa[0].q=-1;
 int i,j,k,max,t,maxi;
 k=0;
 for(i=1;i<n;i++)
 {
  max=-1;
  for(j=0;j<i;j++)
  {
   if( aa[j].w<aa[i].w &&aa[j].s>aa[i].s && aa[j].v>max)
   {//用max寻找当前老鼠之前的体重小于当前老鼠,速度大于当前老鼠,而且当前序列最长的一只老鼠的DP数目
  
    max=aa[j].v;
    t=j;//用t记住这只老鼠的下标
   }
  }
  if(max==-1)
  {//如果没找到合适情况 则为一个新的起点 起点的上一只老鼠为空 这里初始化q为-1
   aa[i].v=1;
   aa[i].q=-1;
  }
  else
  {
   aa[i].v=max+1;//记录DP数目
   aa[i].q=t;//记录上一只老鼠的下标

  }
  if(aa[i].v>k)
  {//记录当前的最优解
   k=aa[i].v;
   maxi=i;//记录最优解的下标
  }
 }
 cout<<k<<endl;
 i=0;
 t=maxi;
 while(t!=-1)
 {//用opt数组将最优解从后向前保存,并逆序输出
  opt[i++]=aa[t].num+1;
  t=aa[t].q;
 }
 for(j=i-1;j>=0;j--)
  cout<<opt[j]<<endl;
 return 0;
}