zoj3306 状压DP

5 篇文章 0 订阅

Kill the Monsters

Time Limit: 7 Seconds Memory Limit: 32768 KB

In order to celebrate the 8th anniversary of ZOJ, watashi introduces a strange game to other ZJU ACM team members. The board of the game consists of 20X20 grids.

There're some monsters in the grid and 40 buttons along the board. Each row and column is controlled by a single button, while each button can be pushed ONLY ONCE.

  • If you push a row-controlling button, the health point of all the monsters in the corresponding row will decrease 1.
  • If you push a column-controlling button, the health point of all the monsters in the corresponding column will decrease 1.

The health point of each monster is 2 initially, and if the monster's health point is 0, we say that the monster has been killed. The goal of the game is to kill as many monsters as possible and you cannot push more than N buttons.

Though Watashi plays the game day and night, he cannot always achieve the perfect goal. Please help him to find the best solution of some specific boards.

Input

The first line of each test case contains the numbers N ( 1 <= N <= 40 ).

Then there're 20 lines, each with 20 characters. The jth character in the ith line correspond to the state in grid (i, j). '.' for the empty grid, '#' for a monster.

The input will contain no more than 10 test cases.

The last test case is followed by one zero.

Output

For each test case output one number, the maximum number of dead monsters.

Sample Input

3
....................
....................
..###...............
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
10
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
0

Sample Output

2
25


题意:每次给出一张20*20的图,#表示拥有两滴血的怪物,有两种减怪物血的方式,一种是整列减1滴血,另一种是整行减1滴血,且每行每列只能减一次。提供n次,问最多能杀掉多少怪物。

思路:主要还是围绕着消除哪些行跟哪些列,并使行+列=n,这样很容易就相当枚举其中一个,行不容易处理,反而列可以用状压dp进行处理。用1表示选取了当前列。接下来只要选取所在列下,对能每行能消除的个数进行排序,选取最多能消除的前几行。

#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<algorithm>
using namespace std;
char mp[25][25];
int cou[1<<20];
int have[20];
void init(){
	memset(cou,0,sizeof(cou));
	for(int i=1;i<(1<<20);i++){
		int temp=i;
		while(temp){
			cou[i]++;
			temp-=(temp&-temp);
		}
	}
}
int cmp(const void *a,const void *b){
	return *(int *)b-*(int *)a;
}
int main(void){
	int n;
	int ans;
	int all;
	init();
	while(scanf("%d",&n),n){
		ans=0;
		memset(have,0,sizeof(have));
		for(int i=0;i<20;i++)
			scanf("%s",mp[i]);
		for(int i=0;i<20;i++)
			for(int j=0;j<20;j++)
				if(mp[i][j]=='#')
					have[i]+=(1<<j);
		for(int i=1;i<(1<<20);i++){
			if(cou[i]>n) continue;
			int res[20];
			for(int j=0;j<20;j++)
				res[j]=cou[i&have[j]];
			qsort(res,20,sizeof(res[0]),cmp);
			int sum=0;
			for(int j=0;j<20&&j<n-cou[i];j++)
				sum+=res[j];
			ans=max(ans,sum);
		}
		printf("%d\n",ans);
	}
	
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值