题目链接:hdu-1160
题目大意:输入几组老鼠的体重还有速度,从其中取n组,使这n组满足随着质量增大速度减小,求最大的n,并输出它们的序号
思路:先按质量从小到大,速度从大到小排列,dp[i]代表前i个数据中最大的n;两个循环,第一个求dp[i],第二个从1到i,如果j与i符合要求,则dp[i]=dp[j]+1;第二层循环循环一遍的,循环到i,求出的最大的dp[i],即为需要记录的dp[i],递推公式为dp[i] = max(dp[j] + 1,dp[i]);关于记录路径就是写个结构体,更新最优解的时候,把前面的那组的序号存到这一个结构体里面;
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct node
{
int w, s, num,pre;//num存序号,pre存前面符合题意的组别的序号
}m[1005];
bool cmp(node a, node b)//按体重排序
{
if (a.w != b.w)return a.w < b.w;
return a.s > b.s;
}
int main()
{
int dp[1005], i, j, k, l, n, t,a,b,max,end;
vector<int> p;//存最后序号的排列
vector<int>::reverse_iterator it;
n = 1;
while (cin >> a >> b)
{
m[n].w = a;
m[n].s = b;
m[n].pre = n;//自己为一组时,初始化为自己
m[n].num = n;
n++;
}
sort(m + 1, m + n, cmp);
fill(dp, dp + 1005, 1);
max = 1, end = 1;//最多的组别和结尾组的序号更新为1
for(i=2;i<n;i++)//dp[1]=1;从第二个dp开始,打表
for (j = 1; j < i; j++)//从1~i遍历
{
if (m[j].w<m[i].w&&m[j].s>m[i].s&&dp[j] + 1 > dp[i])//满足条件则更新最优解,注意最后条件
{
dp[i] = dp[j] + 1;
m[i].pre = j;
}
if (dp[i] >=max)//max存最后的结果n;
{
max = dp[i];
end = i;//结尾组别的序号
}
}
cout << max << endl;
while (max--)
{
p.push_back(m[end].num);
end = m[end].pre;//把符合题意的n个组别的序号依次压进p里面
}
for (it = p.rbegin(); it != p.rend(); it++)
cout << *it << endl;
return 0;
}