您的位置:首页 > 其它

UVa10817 Headmaster's headache[状压DP]

2016-11-03 11:42 423 查看
最后再跟自己强调一次,Think twice,code once.

Headmaster’s Headache

The headmaster of Spring

Field School is consider-

ing employing some new

teachers for certain subjects.

There are a number of teach-

ers applying for the posts.

Each teacher is able to teach

one or more subjects. The

headmaster wants to select

applicants so that each sub-

ject is taught by at least two

teachers, and the overall cost

is minimized.

Input

The input consists of several

test cases. The format of

each of them is explained below:

The rst line contains three positive integers S, M and N. S ( 8) is the number of subjects, M

( 20) is the number of serving teachers, and N ( 100) is the number of applicants.

Each of the following M lines describes a serving teacher. It rst gives the cost of employing him/her

(10000  C  50000), followed by a list of subjects that he/she can teach. The subjects are numbered

from 1 to S. You must keep on employing all of them. After that there are N lines, giving the

details of the applicants in the same format.

Input is terminated by a null case where S = 0. This case should not be processed.

Output

For each test case, give the minimum cost to employ the teachers under the constraints.

Sample Input

2 2 2

10000 1

20000 2

30000 1 2

40000 1 2

0 0 0

Sample Output

60000

题意:

给定m个必选和n个可选,每个选择都有代价和能力点,求代价最小且每个能力点都至少有2的配置。

分析:

典型DP,F[i][j]存至少有1个点的状态,J存至少有2个点的状态,数组存最小代价。

没有RE了好开心,感谢Qwsin小天使QAQ,女票最厉害了QAQ。 不过TLE了(扶额),我看了一下感觉不是常数的问题,因为我为了改RE本来就特意和std写得差不多,而且std也很快常数不应该那么大。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<ctime>
#define ll long long
#define inf 0x3f3f3f3f
#define modd 1e9+7
#define clr(x) memset(x,0,sizeof(x))
#define maxen(x) memset(x,127,sizeof(x))
#define maxer(x) memset(x,0x3f,sizeof(x))
#define minus(x) memset(x,-1,sizeof(x))
#define each(i,n) for(int i=1;i<=n;i++)
#define minn(a,b,c) min(a,min(b,c))
#define maxx(a,b,c) max(a,max(b,c))
#ifdef WIN32
#define lld "%I64d"
#else
#define lld "%lld"
#endif
#define PROC "UVa10817"
//for(int i=1;i<=n;i++)
//(double) (ll) LL (int)
//(double)clock()/CLOCKS_PER_SEC
using namespace std;
const int Maxn=150;
int s,m,n,st1,st2,sum,costy[Maxn],subj[Maxn],f[1<<8][1<<8];
int cnt[15];
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void read(int cur)
{
char tmp=getchar();
while(tmp!='\n'){
if(tmp<='9'&&tmp>='0')
subj[cur]|=1<<(tmp-'0'-1);
if(cur<=m)cnt[tmp-'0'-1]++;
tmp=getchar();
}
if(cur<=m){
st1|=subj[cur];
sum+=costy[cur];}
}
void init()
{
s=read();m=read();n=read();
st1=0;st2=0;sum=0;clr(cnt);
each(i,m+n){
subj[i]=0;
costy[i]=read();
read(i);
}
for(int i=0; i<s; ++i)
if(cnt[i] > 1) st2 |= (1<<i);
maxer(f);
}
void work()
{
f[st1][st2]=sum;
for(int i=m+1;i<=n+m;i++)
for(int s1=(1<<s)-1;s1>=0;s1--)
for(int s2=(1<<s)-1;s2>=0;s2--){
if(f[s1][s2] >= inf) continue;
int st1 = (subj[i]|s1);
int st2 = (subj[i]&s1) | s2;
f[st1][st2] = min(f[st1][st2], f[s1][s2]+costy[i]);
}
printf("%d\n",f[(1<<s)-1][(1<<s)-1]);
}
void debug()
{
//
}
int main()
{
freopen(PROC".in","r",stdin);
//  freopen(PROC".out","w",stdout);
while(1){
init();
if(s)
work();
else break;
}
//debug();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  uva UVA10817 状压DP