11008 - Antimatter Ray Clearcutting

来源:互联网 发布:域名如何跟服务器绑定 编辑:程序博客网 时间:2024/06/08 17:28
/*自己没思路,去网上看了大牛的题解才会的,竟然是2进制状态压缩啊,感觉也不难就是自己想不出来,之前还有一题是10911 - Forming Quiz Teams 也是2进制状态压缩,像这种数据量不大于30,状态转移和每个元素都可能有关系的DP应该都是用状态压缩吧。DP每次最关键的是找两棵没被砍的树然后找到这两棵树所在直线的所有没被砍的树,然后砍掉进入下一状态。 */#include <stdio.h>#include <string.h>#define maxn (1<<17)#define N 20int n,m,d[maxn],x[N],y[N];int isline(int i,int j,int k){int a=x[i]-x[j],b=y[i]-y[j];int c=x[i]-x[k],d=y[i]-y[k];return a*d==b*c;}int min(int a,int b){if(a<b) return a;else return b;}int dp(int ct,int cu){if(d[ct]<(1<<30)) return d[ct];if(cu<=0) return d[ct]=0;if(cu==1) return d[ct]=1;for(int i=0;i<n;i++){if((1<<i)&ct)for(int j=i+1;j<n;j++)if((1<<j)&ct){int t=ct,co=0;for(int k=0;k<n;k++)if((1<<k)&t&&isline(i+1,j+1,k+1)){t-=(1<<k);co++;}d[ct]=min(d[ct],dp(t,cu-co)+1);}}return d[ct];}int main(){int t;scanf("%d",&t);for(int tt=1;tt<=t;tt++){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d%d",&x[i],&y[i]);memset(d,0x7f,sizeof(d));printf("Case #%d:\n",tt);printf("%d\n",dp((1<<n)-1,m));if(t!=tt) printf("\n");}return 0;}

原创粉丝点击