题解:P8816 [CSP-J 2022] 上升点列

· · 题解

题目理解

#include<bits/stdc++.h>
using namespace std;
struct node{
    int x;
    int y;
};
node a[1010];
bool cmp(node l,node r){
    if(l.x!=r.x){
        return l.x<r.x;
    }
    return l.y<r.y;
}
int dp[510][510];
int sum[510][510];
int inf=1e9;
int main(){
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&a[i].x,&a[i].y);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            dp[i][j]=inf;//初始赋值 
        }
    } 
    sort(a+1,a+n+1,cmp);
    for(int len=2;len<=n;len++){
        for(int l=1;l<=n-len+1;l++){
            int r=l+len-1;
            if(a[r].y-a[l].y<0){
                continue;
            }
            dp[l][r]=(a[r].y-a[l].y)+(a[r].x-a[l].x)-1;
            sum[l][r]=(a[r].y-a[l].y)+(a[r].x-a[l].x)+1;

            if(len==2){
                continue;
            }

            for(int k=1;k<=n;k++){
                if(k==l || k==r){
                    continue;
                }
                if(dp[l][k]+dp[k][r]<dp[l][r]){
                    dp[l][r]=dp[l][k]+dp[k][r];
                    sum[l][r]=sum[l][k]+sum[k][r]-1;
                }
            }
        }
    }
    int mx=0;
    for(int l=1;l<=n;l++){
        for(int r=l;r<=n;r++){
            if(a[r].y-a[l].y<0 || dp[l][r]>k){
                continue;
            }
            int len=sum[l][r]+(k-dp[l][r]);
            mx=max(mx,len);
        }
    }
    printf("%d\n",mx);
    return 0; 
}