一开始很简单的以为跟之前写的一样,多加个就可以了,第一问确实没问题,第二问就错的离谱了,看了网上的解题思路,果断自己写了一个,代码写得比较搓
,不过时间复杂度还可以
。
ACcode:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
const int NS=15;
const int INF=1<<30;
struct Point
{
int x,y,c;
} p[NS+1];
int top,flag,lim;
int u,v,t,w,n,m;
int state[1<<NS],tim[1<<NS][NS];
int p2[NS+2],bit[1<<NS][NS];
int dp[1<<NS],r[1<<NS],g[NS+1][NS+1];
int Dist(Point a,Point b)
{
return ceil( sqrt( 1.0*(a.x-b.x)*(a.x-b.x)+1.0*(a.y-b.y)*(a.y-b.y) ) );
}
void prepare()
{
p2[0]=1;
for (int i=1; i<NS; i++)
p2[i]=p2[i-1]<<1;
lim=1<<NS;
for (int t,i=0; i<lim; i++)
{
t=0;
for (int j=0; j<NS; j++)
if (p2[j]&i) bit[i][++t]=j;
bit[i][0]=t;
}
}
int Min(int a,int b)
{
return a<b?a:b;
}
int dp1()
{
int u,v,w,t;
for (int i=0; i<lim; i++)
dp[i]=INF,r[i]=INF;
dp[0]=1,r[0]=0;
for (int i=1; i<lim; i++)
for (int j=1; j<=bit[i][0]; j++)
{
u=bit[i][j],v=i-p2[u],w=r[v]+p[u].c;
if (w<=m)
{
if (dp[i]>dp[v])
dp[i]=dp[v],r[i]=w;
else if (dp[i]==dp[v])
r[i]=Min(w,r[i]);
}
if (p[u].c<=m)
{
if (dp[i]>(dp[v]+1.0))
dp[i]=dp[v]+1,r[i]=p[u].c;
else if (dp[i]==dp[v]+1)
r[i]=Min(p[u].c,r[i]);
}
}
return dp[lim-1]>=INF?-1.0:dp[lim-1];
}
void init()
{
top=0;
memset(state,0,sizeof(state));
for (int s,t,i=0;i<lim;i++)
{
s=0;
for (int j=1;j<=bit[i][0];j++)
t=bit[i][j],s+=p[t].c;
if (s<=m) state[i]=1;
}
}
int dp2()
{
init();
for (int i=0;i<lim;i++)
for (int j=0;j<n;j++)
tim[i][j]=INF;
for (int i=0;i<lim;i++)
dp[i]=INF;
dp[0]=0;
for (int i=0;i<n;i++)
if (p[i].c<=m)
tim[p2[i]][i]=g[n][i];
for (int i=0;i<lim;i++)
if (state[i])
for (int j=1;j<=bit[i][0];j++)
{
u=bit[i][j],v=i-p2[u];
for (int k=1;k<=bit[v][0];k++)
t=bit[v][k],
tim[i][u]=Min(tim[i][u],tim[v][t]+g[t][u]);
dp[i]=Min(dp[i],tim[i][u]+g[u][n]);
}
for (int i=1;i<lim;i++)
{
for (int j=n;j>=0;j--)
if (p2[j]&i){ t=p2[j];break; }
for (int j=i;j!=t;j=i&(j-1))
dp[i]=Min(dp[i],dp[j]+dp[i^j]);
dp[i]=Min(dp[i],dp[t]+dp[i^t]);
}
return dp[lim-1]>=INF?-1:dp[lim-1];
}
int main()
{
prepare();
while (~scanf("%d %d",&n,&m))
{
n--,flag=0,lim=1<<n;
scanf("%d%d",&p[n].x,&p[n].y);
for (int i=0; i<n; i++)
scanf("%d%d",&p[i].x,&p[i].y);
scanf("%d",&p[n].c);
for (int i=0; i<n; i++)
scanf("%d",&p[i].c),
flag+= p[i].c>m?1:0;
if (flag)
{
printf("-1 -1\n");
continue;
}
for (int i=0; i<=n; i++)
for (int j=i+1; j<=n; j++)
g[i][j]=g[j][i]= i==j?0:Dist(p[i],p[j]);
printf("%d %d\n",dp1(),dp2());
}
return 0;
}