hdu4281
分析
好题目,可以看看这位博主的博客:http://blog.csdn.net/acm_cxlove/article/details/7966276
完全就是学习了,以后再回来看看。。
题目
http://acm.hdu.edu.cn/showproblem.php?pid=4281
代码
#include <iostream>
#include <cstring>
#include <ctime>
#include <fstream>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
int n,m;
int x[20],y[20],pa[20];
int ok[(1<<16)+10];
int path[20][20];
int best[(1<<16)+10];
int dp[20][(1<<16)+10];
int cnt=0,state[(1<<16)+10];
int cal(int i,int j)
{
return ceil(sqrt((double)(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])));
}
bool check(int i)
{
int sum=0;
for(int j=0; j<n; j++)
{
if(i&(1<<j))
sum+=pa[j];
}
return m>=sum;
}
void init()
{
cnt=0;
for(int i=0; i<(1<<n); i++)
{
ok[i]=0;
if(check(i))
{
ok[i]=1;
state[cnt++]=i;
}
best[i]=inf;
for(int j=0; j<n; j++)
dp[j][i]=inf;
}
dp[0][1]=0;
}
int solve1()
{
int dp[1<<n];
for(int i=0; i<(1<<n); i++)
dp[i]=inf;
dp[0]=0;
for(int i=0; i<cnt; i++)
{
for(int j=(1<<n)-1; j>=0; j--)
{
if(dp[j]==inf) continue;
if(j&state[i]) continue;
dp[state[i]|j]=min(dp[state[i]|j],dp[j]+1);
}
}
return dp[(1<<n)-1];
}
int TSP()
{
for(int i=0; i<(1<<n); i++)
{
if(ok[i])
{
for(int j=0; j<n; j++)
{
if(i&(1<<j))
{
best[i]=min(best[i],dp[j][i]+path[j][0]);
for(int k=0; k<n; k++)
{
if(!(i&(1<<k)))
dp[k][i|(1<<k)]=min(dp[k][i|(1<<k)],dp[j][i]+path[j][k]);
}
}
}
}
}
for(int i=0; i<(1<<n); i++)
if(i&1)
for(int j=i&(i-1); j; j=i&(j-1))
best[i]=min(best[i],best[j]+best[(i-j)|1]);
return best[(1<<n)-1];
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=0; i<n; i++) scanf("%d %d",&x[i],&y[i]);
for(int i=0; i<n; i++) scanf("%d",&pa[i]);
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
path[i][j]=cal(i,j);
init();
int ans1=solve1();
if(ans1==inf)
{
printf("-1 -1\n");
continue;
}
printf("%d %d\n",ans1,TSP());
}
return 0;
}