题目链接:传送门
中文翻译:
思路:将体重递增排序,iq递减排序,那么问题就变成了求iq的递减序列
注意事项:判断方面需要
if(e[i].w>e[j].w&&e[i].iq<e[j].iq&&dp[j]+1>dp[i]) { dp[i]=dp[j]+1; path[i]=j;//标记序列 }
-
体重是严格递增的,所以需特判下体重是否严格递增,后边的就是递减序列的条件了
-
路径同时需要保存下来,(递归输出)
-
当前i保存紧跟他后边的那个数j
统计答案:
if(ans<=dp[i]) { pos=i; ans=dp[i]; }
-
等号不能省,原因:前边可能有等长的序列,我们要的序列n尽可能大
输出答案:
-
递归输出,因为我们最后标记的是序列最后一个数,递归反着输出
code
#include<iostream>
#include<algorithm>
using namespace std;
int dp[1005],path[1005],pos,ans;
struct ele{
int w;
int iq;
int id;
}e[1005];
bool cmp(struct ele a,struct ele b)
{
if(a.w==b.w)
return a.iq>b.iq;
else return a.w<b.w;
}
void print(int x){
if(ans--){
print(path[x]);
printf("%d\n",e[x].id);
}
}
int main()
{
int cnt=0;
while(scanf("%d%d",&e[cnt].w,&e[cnt].iq)!=EOF){
e[cnt].id=cnt+1;
dp[cnt]=1;
++cnt;
}
sort(e,e+cnt,cmp);
for(int i=0;i<cnt;i++){
for(int j=0;j<i;j++)
if(e[i].w>e[j].w&&e[i].iq<e[j].iq&&dp[j]+1>dp[i])//体重严格递增的(有的体重相等,需特判)
{
dp[i]=dp[j]+1;
path[i]=j;//标记序列
}
if(ans<=dp[i])//等号不能省,我们的n是尽可能的最大值
{
pos=i;
ans=dp[i];
}
}
printf("%d\n",ans);
print(pos);//递归输出序列
//cout<<path[8]<<endl;
return 0;
}