UVA 11008--Antimatter Ray Clearcutting+状态压缩记忆化搜索

题目链接:点击进入

最多只有16个点,如果不用状态压缩的话,最优子结构没法找到。所以我们进行状态压缩,用一个数表示当前的状态,对应二进制位为1表示该位置的树还未被砍掉,为0表示已被砍掉,初始状态为(1<

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

#define maxn  20
#define INF 0x3f3f3f3f

typedef struct
{
   int x,y;
}P;
P p[maxn];

int dp[(1<<maxn)+10],n,m;
int cnt[1<<maxn],s[maxn][maxn];

int check(int i,int j,int k)
{
     return (p[i].y-p[j].y)*(p[j].x-p[k].x)==(p[i].x-p[j].x)*(p[j].y-p[k].y);
}

int Count(int x)
{
     int num=0;
     while(x)
     {
         num++;
         x=x&(x-1);
     }
     return num;
}

int dfs(int x)
{
    if(dp[x]!=-1) return dp[x];
    if(cnt[x]<=n-m) return dp[x]=0;
    if(cnt[x]==1) return dp[x]=1; ///要注意只剩一个点的情况
    int tmp=INF;
    for(int i=0;i<n;i++)
      for(int j=i+1;j<n;j++)
      {
            if(((1<<i)&x)&&((1<<j)&x))
            {
                  int t=dfs(x&s[i][j]);
                  if(t+1<tmp)
                     tmp=t+1;
            }
      }
      return dp[x]=tmp;
}

int main()
{
      int t,Case=0;
      freopen("in.txt","r",stdin);
      scanf("%d",&t);
      while(t--)
      {
           scanf("%d%d",&n,&m);
           for(int i=0;i<n;i++)
              scanf("%d%d",&p[i].x,&p[i].y);
           for(int i=0;i<n;i++)
              for(int j=i+1;j<n;j++)
                 s[i][j]=(1<<n)-1;
           for(int i=0;i<=(1<<n)-1;i++)
              cnt[i]=Count(i);
           for(int i=0;i<n;i++)
             for(int j=i+1;j<n;j++)
                  for(int k=0;k<n;k++)
                      if(check(i,j,k))
                           s[i][j]-=(1<<k);
           memset(dp,-1,sizeof(dp));
           int ans=dfs((1<<n)-1);
           printf("Case #%d:\n%d\n",++Case,ans);
           if(t) printf("\n");
      }
  return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-13 11:46:07

UVA 11008--Antimatter Ray Clearcutting+状态压缩记忆化搜索的相关文章

uva 11008 Antimatter Ray Clearcutting(DFS + 记忆化搜索)

uva 11008 Antimatter Ray Clearcutting It's year 2465, and you are the Chief Engineer for Glorified Lumberjacks Inc. on planet Trie. There is a number of trees that you need to cut down, and the only weapon you have is a high-powered antimatter ray th

Doing Homework---hdu1074(状态压缩&amp;&amp;记忆化搜索)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1074 有n(n<=15)门课需要做作业,每门课所需时间是used_time以及每门课作业上交的最后期限是deadline,晚交一天扣一分,现在来安排最好的写作业计划,让最终的扣除分数最少:   由于n的取值范围不大所以我们可以枚举除所有的状态进行判断是否是最优的即可,状态数为2^n-1; 我们可以用状态压缩来表示出各种状态:二进制中的第i为为1代表第i门课已经完成了. #include <cstd

ACM学习历程—ZOJ3471 Most Powerful(dp &amp;&amp; 状态压缩 &amp;&amp; 记忆化搜索 &amp;&amp; 位运算)

Description Recently, researchers on Mars have discovered N powerful atoms. All of them are different. These atoms have some properties. When two of these atoms collide, one of them disappears and a lot of power is produced. Researchers know the way

UVA 11008 Antimatter Ray Clearcutting(DP)

It's year 2465, and you are the Chief Engineer for Glorified Lumberjacks Inc. on planet Trie. There is a number of trees that you need to cut down, and the only weapon you have is a high-powered antimatter ray that will cut through trees like butter.

uva 10581 - Partitioning for fun and profit(记忆化搜索+数论)

题目链接:uva 10581 - Partitioning for fun and profit 题目大意:给定m,n,k,将m分解成n份,然后按照每份的个数排定字典序,并且划分时要求ai?1≤ai,然后输出字典序排在k位的划分方法. 解题思路:因为有ai?1≤ai的条件,所以先记忆化搜索处理出组合情况dp[i][j][s]表示第i位为j,并且剩余的未划分数为s的总数为dp[i][j][s],然后就是枚举每一位上的值,判断序列的位置即可. #include <cstdio> #include

UVa 10651 Pebble Solitaire (DP 卵石游戏 记忆化搜索)

 题意  给你一个长度为12的字符串  由字符'-'和字符'o'组成  其中"-oo"和"oo-"分别可以通过一次转换变为"o--"和"--o"  可以发现每次转换o都少了一个  只需求出给你的字符串做多能转换多少次就行了 令d[s]表示字符串s最多可以转换的次数  若s可以通过一次转换变为字符串t  有d[s]=max(d[s],d[t]+1) #include<iostream> #include<s

uva 10285 The Tower of Babylon(记忆化搜索)

Problem C Longest Run on a Snowboard Input: standard input Output: standard output Time Limit: 5 seconds Memory Limit: 32 MB Michael likes snowboarding. That's not very surprising, since snowboarding is really great. The bad thing is that in order to

状压DP+记忆化搜索 UVA 1252 Twenty Questions

题目传送门 1 /* 2 题意:给出一系列的01字符串,问最少要问几个问题(列)能把它们区分出来 3 状态DP+记忆化搜索:dp[s1][s2]表示问题集合为s1.答案对错集合为s2时,还要问几次才能区分出来 4 若和答案(自己拟定)相差小于等于1时,证说明已经能区分了,回溯.否则还要加问题再询问 5 */ 6 /************************************************ 7 * Author :Running_Time 8 * Created Time :

ACM-ICPC 2018 徐州赛区网络预赛 B BE, GE or NE(博弈,记忆化搜索)

链接https://nanti.jisuanke.com/t/31454 思路 开始没读懂题,也没注意看数据范围(1000*200的状态,记忆化搜索随便搞) 用记忆化搜索处理出来每个状态的胜负情况 因为每个人都会选择最优的,因此记忆化搜索的过程其实就是在模拟两个人每一步决策所带来的胜负情况, 只要返回一个必胜,就直接返回(因为会选择最优) 然后在没有返回必胜的状态下,有平局就选择平局,没有平局就只能输了 #include<bits/stdc++.h> #define st 100 #defin