首页 > 其他 > 详细

codechef Mike and Stamps

时间:2014-04-19 01:38:29      阅读:412      评论:0      收藏:0      [点我收藏+]

All submissions for this problem are available.

Read problems statements in Mandarin Chinese and Russian.

Mike is fond of collecting stamps. He has a lot of rare and unusual ones in his collection. Unfortunately, a few days ago he was fired from his well-paid job.

But he doesn‘t complain about that, he acts! That‘s why Mike picked up N stamps from his collection and is going to sell them. He has already placed an announcement on the Internet and got M offers. Each offer can be described as a set of stamps, that the buyer wants to buy. Now Mike needs your help to choose a set of offers, that he should accept.

He can‘t accept offers partially. Also, as far as Mike has the only copy of each stamp, he can sell one stamp to at most one buyer.

Of course, Mike wants to maximize the number of accepted offers. Help him!

Input

The first line contains two integer N and M, denoting the number of the stamps and the number of the offers.

The next M lines contain the descriptions of the offers. The (i+1)‘th line of the input contains the description of the i‘th offer and corresponds to the following pattern: Ki Ai, 1 Ai, 2, ..., Ai, KiKi - is the number of the stamps, which the i‘th buyer wants to buy, Ai - is the list of the stamps sorted in the ascending order.

 

Output

Output should contain the only integer, denoting the maximal number of the offers, that Mike can accept.

 

Constraints

1 ≤ N ≤ 20,000

1 ≤ M ≤ 20

1 ≤ Ki

 

Example

Input:
4 3
2 1 2
2 2 3
2 3 4

Output:
2

 

Explanation

In the example test Mike should accept the first and the third offer.


今天重做了一下codechef以前的错题。。结果发现自己真的不在状态。。

题意:有n张邮票卖。但是顾客可能一次要几张。。

问你最多可以卖给多少个顾客。每种邮票只有一张。

题解:首先看到顾客最多只有20个。所以就算是枚举也只是2^20 100w

不会超时。而且首先是计算出每两个顾客是否冲突。

然后就递归枚举。。加少量的剪枝。。

但是递归更新最大值时wa了很多次。后来才发现有一种情况没更新。。。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
int stamp[22][20002];
int xy[22][22];
int num[22],n,m,ans,f[22];
int max(int a,int b) {
	return a>b?a:b;
}
int ok(int k,int p) {
	int i,j = 0;
	for(i=0;i<num[k] && j<num[p];) {
		if(stamp[k][i]==stamp[p][j]) return 0;
		else if(stamp[k][i]>stamp[p][j]) j++;
		else i++;
	}
	return 1;
}
void make() {
	int i,j;
	for(i=0;i<m-1;i++)
	for(j=i+1;j<m;j++)
	xy[i][j] = xy[j][i] = ok(i,j);
}
bool work(int p,int a[],int len) {
	int i;
	for(i=0;i<len;i++) {
		if(xy[a[i]][p]==0)
		return 0;
	}
	return 1;
}
void DFS(int p,int len,int a[]) {
	int i;
	
	if(p>=m) {
	ans = max(ans,len);
	return ;
	}
	for(i=p;i<m;i++) {
		if(f[i]==0 && work(i,a,len)) {
			f[i] = 1;
			a[len] = i;
			DFS(i+1,len+1,a);
			f[i] = 0; 
		}
	}
	ans = max(ans,len);  //递归是忘记了最后一个不可以选择时就进不了return这个语句。然后就更新不了最大值
}						//为什么要犯这种错误。。。。
int main()
{
    int i,j,p;
    int a[22];
    scanf("%d%d",&n,&m);
    for(i=0;i<m;i++) {
    	scanf("%d",&num[i]);
    	for(j=0;j<num[i];j++)
    	scanf("%d",&stamp[i][j]);
    }

    make();
    ans = 1;
    DFS(0,0,a);
     printf("%d\n",ans);
    return 0;  
}    




codechef Mike and Stamps,布布扣,bubuko.com

codechef Mike and Stamps

原文:http://blog.csdn.net/min_lala/article/details/24045231

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!