区间DP,换了数据后WA on #15 #16,显示答案输出了 0,求hack。
#include<bits/stdc++.h>
#define ld long double
using namespace std;
namespace LgxTpre
{
static const int MAX=2010;
static const int mod=998244353;
static const int INF=2147483647;
static const ld inf=9999999999.0;
int n,k;
int L,R,op;
double maxy,now;
struct point
{
ld x,y;
}a[MAX];
int pre[MAX][MAX][2];
double dp[MAX][MAX][2];
vector<int> ans;
inline double dis(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
inline void mian()
{
cin>>n;
for(int i=1;i<=n;++i)
{
cin>>a[i].x>>a[i].y,a[i+n]=a[i];
if(a[i].y>maxy) maxy=a[i].y,k=i;
}
memset(dp,0x7f,sizeof dp);
dp[k][k][0]=dp[k][k][1]=dp[k+n][k+n][0]=dp[k+n][k+n][1]=0.0;
for(int len=2;len<=n;++len)
for(int l=1,r=l+len-1;r<(n<<1);++l,++r)
if((l<=k&&k<=r)||(l<=k+n&&k+n<=r))
{
dp[l][r][0]=min(dp[l+1][r][0]+dis(a[l],a[l+1]),dp[l+1][r][1]+dis(a[l],a[r]));
pre[l][r][0]=dp[l][r][0]==dp[l+1][r][1]+dis(a[l],a[r]);
dp[l][r][1]=min(dp[l][r-1][1]+dis(a[r-1],a[r]),dp[l][r-1][0]+dis(a[l],a[r]));
pre[l][r][1]=dp[l][r][1]==dp[l][r-1][1]+dis(a[r-1],a[r]);
}
now=inf;
for(int i=1;i<=n;++i)
for(int j=0;j<=1;++j)
if(dp[i][i+n-1][j]<now)
now=dp[i][i+n-1][j],L=i,R=i+n-1,op=j;
while(L!=R)
{
if(op==1) ans.push_back(R),op=pre[L][R][op],--R;
else ans.push_back(L),op=pre[L][R][op],++L;
}
ans.push_back(k); reverse(ans.begin(),ans.end());
for(int i=0;i<ans.size();++i)
cout<<(ans[i]>n?ans[i]-n:ans[i])<<" ";
return;
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
LgxTpre::mian();
return (0-0);
}