LightOJ1037-Agent 47-状态压缩

题目大意:有一个杀手,他一开始有一把枪,每次开枪只能造成一点伤害,他需要消灭n个敌人,每个敌人有各自的health[i], 并且有武器,消灭敌人就可以获得他的武器用来消灭其他敌人;

题目解析:n特别小,并且序列不需要有顺序,很明显是状态dp,dp[i]表示消灭序列i时所需要最少的开枪次数,然后dp的时候枚举没有消灭的敌人,选择消灭过的敌人们的武器与自己的作比较,这样肯定是最优解,然后dp就可以转移了;

AC代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#define inf 0x3ffffff
using namespace std;
int dp[(1<<15)+10],health[20],gun[20][20];
int main()
{
	int cas,cnt=1,i,j,k,len,n,ma;
	string s;
	scanf("%d",&cas);
	while(cas--)
	{
		cin>>n;
		for(i=0;i<n;i++)
		{
			scanf("%d",&health[i]);
		}
		for(i=0;i<n;i++)
		{
			cin>>s;
			for(j=0;j<n;j++)
			{
				gun[i][j]=s[j]-'0';
			}
		}
		len=1<<n;
		for(i=0;i<len;i++)
			dp[i]=inf;
		dp[0]=0;
		for(i=0;i<n;i++)
		{
			dp[1<<i]=health[i];
		}
		for(i=0;i<len;i++)
		{
			for(j=0;j<n;j++)
			{
				if((i&(1<<j))==0)
				{
					ma=1;
					for(k=0;k<n;k++)
					{
						if(i&(1<<k))
						{
							ma=max(ma,gun[k][j]);
						}
					}
					if(health[j]%ma==0)
						dp[i|(1<<j)]=min(dp[i|(1<<j)],dp[i]+health[j]/ma);
					else 
						dp[i|(1<<j)]=min(dp[i|(1<<j)],dp[i]+health[j]/ma+1);
				}
			}
		}
		printf("Case %d: %d\n",cnt++,dp[len-1]);
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值