solvedp挂了,调不来,求救……
#include <bits/stdc++.h>
using namespace std;
int n,k;
struct star{
int x,y;
bool operator<(const star&s) const{
return x<s.x||x==s.x&&y<s.y;
}
};
star s[1009];
void solvenok(){
int f[1009]; //以i为尾部的最长
for (int i=1;i<=n;++i){
f[i]=1;
for (int j=1;j<i;++j){
if (abs(s[i].x-s[j].x)+abs(s[i].y-s[j].y)==1&&s[i].y>=s[j].y){
f[i]=max(f[i],f[j]+1);
}
}
}
int ans=*max_element(f+1,f+n+1);
printf("%d\n",ans);
}
void solven10(){ //尽可能多地找点,使他们之间的(曼哈顿距离-1)之和<=k
int ans=k; //一个都不选
bool ok[20];
vector<int> chosen;
for (int i=1;i<pow(2,n);++i){
int pre=0;chosen.clear();
int t=i;
for (int j=n;j>=1;--j) if (t>=pow(2,j-1)) t-=pow(2,j-1),chosen.push_back(j);
reverse(chosen.begin(),chosen.end());
int cnt=0;bool flag=true;
for (int a=0;a<chosen.size()-1;++a){
int u=chosen[a],v=chosen[a+1];
if (s[u].y>s[v].y) flag=false;
cnt+=(abs(s[u].x-s[v].x)+abs(s[u].y-s[v].y)-1);
}
if (cnt>k||!flag) continue;
else pre=k+chosen.size(),ans=max(ans,pre);
}
printf("%d\n",ans);
}
void solvedp(){
int f[1009][109],x[1009],y[1009],ans=-1;f[1][0]=k+1;
for (int i=1;i<=n;++i) x[i]=s[i].x,y[i]=s[i].y;
for (int i=1;i<=n;++i){
for (int j=0;j<=k;++j){
//if (i==1&&j==0) continue;
f[i][j]=max(f[i][j-1]+1,j+1);
for (int u=1;u<i;++u){
if (y[i]<y[u]) continue;
int left=j-(abs(x[i]-x[u])+abs(y[i]-y[u]))+1;
if (left<0) continue;
f[i][j]=max(f[i][j],f[u][left]+(abs(x[i]-x[u])+abs(y[i]-y[u])));
}
ans=max(ans,f[i][j]);
}
}
printf("%d\n",ans);
}
int main(){
cin>>n>>k;for (int i=1;i<=n;++i) cin>>s[i].x>>s[i].y;sort(s+1,s+n+1);
if (k==0) solvenok();
else if (n<=10) solven10();
else solvedp();
return 0;
}