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 that will cut through trees like butter. Fuel cells for the antimatter ray are very expensive, so your strategy is: stand somewhere in the forest and shoot the ray in some chosen direction. This will cut down all the trees that lie on the line in that direction. Given the locations of several trees and the number of trees that you are required to cut, what is the minimum number of shots that you need to fire?

Input

The first line of input gives the number of cases, N (at most 20). N test cases follow. Each one starts with 2 lines containing the integersn (the number of trees in the forest, at most 16) and m (the number of trees you need to cut, at most n). The next n lines will each give the (x,y) coordinates of a tree (integers in the range [-1000, 1000]).

Output

For each test case, output the line “Case #x:”, where x is the number of the test case. On the next line, print the number of antimatter ray shots required to cut down at least m trees. Print an empty line between test cases.

Sample Input Output for Sample Input

2

4

4

0 0

0 1

1 0

1 1

9

7

0 0

1 1

0 2

2 0

2 2

3 0

3 1

3 2

3 4

Case #1:

2

Case #2:

2

Notes

In the first test case, you can cut down 4 trees by standing at (0, -1) and firing north (cutting 2 trees) and then standing at (1, -1) and again firing north (cutting 2 more trees).

In the second test case, you should stand at (3,-1) and fire north (cutting 4 trees) and then stand at (-1, -1) and fire north-east (cutting 3 more trees).

题目大意:有n棵树,要砍掉m棵,你有一把可以射一条直线的枪,可以帮助你砍掉一条线上所有的树,但是这种枪的子弹非常贵,所以需要你来算出最少需要多少枪,就可以砍掉所有的树。

解题思路:将n棵树的状态压缩为0和1,1代表树还在,0代表数已经被砍了。DFS时,先找出还未被砍掉的两棵树,然后找出在这两棵树连成的直线上的未被砍掉的树(包括其本身两点),将该树的位数置为0,然后以新的状态进入下一层DFS,直到砍完m棵树,进行对Min的维护。

PS:当下一层DFS完结时,要记得恢复这一层砍掉的树的位数(回溯)。当只剩一棵树时,需要特判。要记录每一个状态,防止重复搜查。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
struct poi{
    int x, y;
} p[25];
int rec[25];
int vis[1 << 20];
int n, m, Min;
int check(poi a, poi b, poi c) {
    int px = b.x - a.x, py = b.y - a.y;
    int qx = c.x - b.x, qy = c.y - b.y;
    if ((qx * py) == (qy * px)) return 1;
    else return 0;
}
int DFS(ll now, int cur, int cnt) {
    if (vis[now]) return 0; //dp数组记录的是当前压缩状态now下的最小
    else if (cur <= 0) {
        if (cnt < Min) Min = cnt;
        return 0;
    } else if(cur == 1) { //只剩一棵树
        Min = min(Min, cnt + 1);
        return 0;
    }
    if (cnt >= Min) return 0;
    for (int i = 0; i < n; i++) {
        if ( !(now & (1 << i)) ) continue;
        for (int j = i + 1; j < n; j++) {
            if ( !(now & (1 << j)) ) continue;
            int c = 0;
            int tmp = now;
            for (int k = i; k < n; k++) {
                if (now & (1 << k) && check(p[i], p[j], p[k])) {
                    c++;
                    tmp -= (1 << k);
                }
            }
            vis[now] = 1;
            DFS(tmp, cur - c, cnt + 1);
        }
    }
}
int main() {
    int T, Case = 1;
    scanf("%d", &T);
    while (T--) {
        memset(vis, 0, sizeof(vis));
        printf("Case #%d:\n", Case++);
        Min = 20;
        scanf("%d %d", &n, &m);
        for (int i = 0; i < n; i++) {
            scanf("%d %d", &p[i].x, &p[i].y);
        }
        ll now = (1 << n) - 1;
        DFS(now, m, 0);
        printf("%d\n", Min);
        if (T) printf("\n");
    }
    return 0;
}
时间: 2024-10-14 08:08:23

uva 11008 Antimatter Ray Clearcutting(DFS + 记忆化搜索)的相关文章

uva11008 - Antimatter Ray Clearcutting(二进制+记忆化搜索)

题目:uva11008 - Antimatter Ray Clearcutting(二进制+记忆化搜索) 题目大意:给出n棵树的坐标,每次砍树能够将在同一直线上的树一起砍掉,然后给出要求你至少砍掉的树的数量,问你要达到这个要求需要砍多少次. 解题思路:因为这题的树的数量比较小(16), 并且只有砍和不砍两种选择,可以用二进制数将状态表示出来.大致思路是:每次都将当前状态下的还没砍的树中选择两棵,在将和这两个树在同一直线上的树一起砍掉,得到新的状态.如果已经>=K棵了,就可以返回0了.一般来说,每

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.

hdu 1501 Zipper (dfs+记忆化搜索)

Zipper Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6491    Accepted Submission(s): 2341 Problem Description Given three strings, you are to determine whether the third string can be formed

ZOJ 3644 Kitty&#39;s Game dfs,记忆化搜索,map映射 难度:2

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4834 从点1出发,假设现在在i,点数为sta,则下一步的点数必然不能是sta的因数,所以不会形成环,只需从1直接走,走到n即可. 但是如果这样的话时空复杂度就都是nk,明显不满足题意,而这个时候我们可以想到,每个状态都必然是k的约数,(点数不是k的约数的节点不在路上,可以无视),而约数的个数也就k^0.5个,可以直接用map映射,这样时空复杂度都是n*k^0.5,可以解出答案

HDU 5024 Wang Xifeng&#39;s Little Plot (枚举 + DFS记忆化搜索)

Wang Xifeng's Little Plot Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 513    Accepted Submission(s): 338 Problem Description <Dream of the Red Chamber>(also <The Story of the Stone>)

How many ways(dfs+记忆化搜索)

Problem Description 这是一个简单的生存游戏,你控制一个机器人从一个棋盘的起始点(1,1)走到棋盘的终点(n,m).游戏的规则描述如下: 1.机器人一开始在棋盘的起始点并有起始点所标有的能量. 2.机器人只能向右或者向下走,并且每走一步消耗一单位能量. 3.机器人不能在原地停留. 4.当机器人选择了一条可行路径后,当他走到这条路径的终点时,他将只有终点所标记的能量. [center] [img]../../../data/images/C113-1003-1.gif[/img]

不要62 hdu 2089 dfs记忆化搜索

题目:http://acm.hdu.edu.cn/showproblem.php?pid=2089 题意: 给你两个数作为一个闭区间的端点,求出该区间中不包含数字4和62的数的个数 思路: 数位dp中的 dfs 记忆化搜索方法解. 模板: int dfs(int i, int s, bool e) { if (i==-1) return s==target_s; if (!e && f[i][s] != -1) return f[i][s]; int res = 0; int u = e?

uva 1076 - Password Suspects(AC自动机+记忆化搜索)

题目链接:uva 1076 - Password Suspects 题目大意:有一个长度为n的密码,存在m个子串,问说有多少种字符串满足,如果满足个数不大于42,按照字典序输出. 解题思路:根据子串构建AC自动机,然后记忆化搜索,dp[i][u][s]表示第i个字符,在u节点,匹配s个子串. #include <cstdio> #include <cstring> #include <queue> #include <string> #include <

poj1088滑雪(dfs+记忆化搜索、备忘录)

题目信息: Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道载一个区域中最长底滑坡.区域由一个二维数组给出.数组的每个数字代表点的高度.下面是一个例子 1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9 一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小.在上面的例子中,一条可滑