uva 11008

来源:互联网 发布:高速过路费计算器软件 编辑:程序博客网 时间:2024/05/17 13:41

uva 11008

状态压缩+记忆化搜索

#include<stdio.h>#include<string.h>#define max 20#define maxn 2<<18#define INF 1<<30int min(int a,int b){    return a>b?b:a;}int g[max][max],f[maxn],limit,x[max],y[max];int m,n;int dp(int tree){    if(f[tree]!=-1)        return f[tree];    int i,j,k,l,t;    t=0;    for(i=0;i<n;i++)    {        if((1<<i)&tree)            t++;    }    if(t<=limit)    {        f[tree]=0;        return 0;    }    if(t==1)    {        f[tree]=1;        return 1;    }    else    {        f[tree]=INF;        int ans;        for(i=0;i<n;i++)        {            if( (1<<i)&tree )                for(j=0;j<n;j++)                {if(i==j)continue;                    if( (1<< j)&tree && g[i][j] )                    ans=dp(tree&(~g[i][j]))+1,                    f[tree]=min(f[tree],ans);                }        }        return f[tree];    }}int main(){    int i,j,k,l,t;    scanf("%d",&l);    for(t=1;t<=l;t++)    {        scanf("%d %d",&n,&m);        limit=n-m;        for(i=0;i<n;i++)        {            scanf("%d %d",&x[i],&y[i]);        }        memset(g,0,sizeof(g));        memset(f,-1,sizeof(f));        for(i=0;i<n;i++)       //任意两棵树间连线中的树的状态        {            for(j=0;j<n;j++)            {                if(i==j)                    continue;                for(k=0;k<n;k++)                {                    if((y[i]-y[j])*(x[k]-x[j])==(y[k]-y[j])*(x[i]-x[j]))                        g[i][j]=g[i][j]|(1<<k);                }            }        }        printf("Case #%d:\n%d\n",t,dp((1<<n)-1));        if(t!=l)            printf("\n");    }    return 0;}


原创粉丝点击