D. Mysterious Present
如果不考虑card只考虑信封 那么先对所有信封排序(先按w从小到大排,如果w一样按h从小到大排)
然后就是对信封的h n²求最长上升子序列(同时要考虑到w可能相等) 考虑card 只有宽和高都大于w和h的才能进行转移
因此初始化时让dp[i]=1 if(a[i].w>W&&a[i].h>H)否则为0 且只有在dp[j]!=0时才能发生转移 发生转移时记录路径
code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
const int N = 5005;
struct node
{
int w,h,id;
}a[N];
bool cmp(node a,node b)
{
if(a.w!=b.w) return a.w<b.w;
else return a.h<b.h;
}
int dp[N],path[N],res[N];
int main()
{
ios::sync_with_stdio(false);
int n,W,H;
cin>>n>>W>>H;
for(int i=1;i<=n;i++)
{
cin>>a[i].w;
cin>>a[i].h;
a[i].id=i;
}
sort(a+1,a+1+n,cmp);
//初始化
for(int i=1;i<=n;i++)
{
if(a[i].w>W && a[i].h>H)
dp[i] = 1;
}
//dp
for(int i=2;i<=n;i++)
{
for(int j=1;j<i;j++)
{
if(dp[j]==0) continue;//这步很关键
if(a[i].h>a[j].h&&a[i].w>a[j].w && dp[j]+1>dp[i])
{
dp[i] = dp[j]+1;
path[i]=j; //j->i;
}
}
}
int ans=0,ind=0;//ind要初始化成0,否则在ans=0的情况下会出问题
for(int i=1;i<=n;i++)
{
if(dp[i]>ans)
{
ans = dp[i];
ind = i;
}
}
cout<<ans<<endl;
int cnt=0;
while(ind!=0)
{
res[++cnt]=ind;
ind = path[ind];
}
for(int i=cnt;i>=1;i--)
{
if(i==cnt) cout<<a[res[i]].id;
else cout<<" "<<a[res[i]].id;
}
}

浙公网安备 33010602011771号