UVA 11008 Antimatter Ray Clearcutting

状态DP,以dp[i]记录砍掉的树的状态为 i 时的最少发射激光数,对于每个状态考虑将当前状态下未被砍的树中选一颗来砍,则考虑两种情况,一个是这颗树需要单独一束激光来砍,另一个就是这棵树和其他已经被砍的某一颗树形成一条线,而在这条线上的点都可以被砍掉,所以求砍这个方向的前一个状态时需要将在这条线上的点都减掉。

具体说明看代码:

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <map>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <cstdlib>
#include <algorithm>
using namespace std;
//typedef __int64 int64;
typedef long long ll;
#define M 100005
#define max_inf 0x7f7f7f7f
#define min_inf 0x80808080
#define mod 1000000007

int n , m , x[25] , y[25];
int dp[1<<22];

bool Judge(int k)//判断当前状态砍掉的树时多少棵树
{
	int num = 0;
	while (k)
	{
		num += (k&1);
		k >>= 1;
	}
	return m <= num;
}

void Solve()
{
	int i , j , k , l , up = 1<<n , tp[25] , ans = max_inf;
	memset(dp , max_inf , sizeof dp);
	dp[0] = 0;
	for (i = 0 ; i < up ; i++)
	{
		for (j = 0 ; j < n ; j++)
		{
			if (i & (1<<j))continue;//若第j颗树已经在状态i中,则继续
			int next = i+(1<<j);//砍掉这棵树后的下一个状态
			dp[next] = min(dp[next],dp[i]+1);

			int temp = i , cnt = 0;
			for (k = 0 ; k < n ; k++)//记录状态i里,被砍掉的树
			{
				if (temp&1)tp[cnt++] = k;
				temp >>= 1;
			}


			for (k = 0 ; k < cnt ; k++)//确定一个方向
			{
				temp = i;
				for (l = 0 ; l < cnt ; l++)
				{
					//将这个方向上的点都减掉
					if ( (y[j]-y[tp[k]])*(x[tp[l]]-x[j]) == (x[j]-x[tp[k]])*(y[tp[l]]-y[j]) ) temp -= (1<<tp[l]);
				}
				dp[next] = min(dp[next] , dp[temp]+1);
			}
		}
		if (Judge(i))ans = min(ans,dp[i]);
	}
	printf("%d\n",ans);
}

int main()
{
	int t , i , tcase = 1;
	scanf("%d",&t);
	while (t--)
	{
		scanf("%d%d",&n,&m);
		for (i = 0 ; i < n ; i++)scanf("%d%d",x+i,y+i);
		if (tcase > 1)printf("\n");
		printf("Case #%d:\n",tcase++);
		Solve();
	}
	return 0;
}


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值