Exercises
Pressure DP + 01 Backpack
In addition to each teacher, each job seeker may choose not to choose. That's the equivalent of 01 backpacks.
It just turns the representation of the State into a binary form.
There are 3 states of the problem
1. Courses that no one teaches
2. Only one person teaches the course S1
3. At least two people teach the course S2
Since it is at least 2 people taught, it is not possible to transition from 3rd State to 2nd state. But it's easy to move from the second state to the 3rd state, so what if I transition from the first state to a second state?
int t = ((1 << s)-1) ^ (j | k);
int m1 = st[i] & T, m2 = st[i] & j;
T represents a course that neither S1 nor S2 have.
M1 says how many of the courses taught by job seekers are in T, to facilitate courses that have never been taught to a single person.
M2 says that in a course where only one person teaches, a job seeker can teach a course. Easy conversion to at least 2 people taught courses
Code:
#include <bits/stdc++.h>using namespacestd;#definePB Push_back#defineMP Make_pair#defineSe Second#defineFS First#defineLson l,m,rt<<1#defineRson m+1,r,rt<<1|1#definePII pair<int,int>#definell Long LongConst intMAXN = -+ -+5;Const intMaxs =8;Const intINF =100000000;intN, M, s;intc[MAXN], st[MAXN], dp[MAXN [1<< Maxs [1<<Maxs];intMain () {intx; stringLine ; while(Getline (cin,line)) {StringStream SS (line); SS>> s >> m >>N; if(s = =0) Break; for(inti =1; I <= m + N; i + +) {getline (cin, line); StringStream SS (line); SS>>c[i]; st[i]=0; while(ss >> X) st[i] |= (1<< (X-1 ) ); } memset (DP,0x3f,sizeof(DP)); dp[0][0][0] =0; for(inti =1; I <= n + m; i + + ) { for(intj =0; J < (1<< s); J + + ) for(intK =0; K < (1<< s); K + + ) { if(J & K)Continue; if(i > m) dp[I [j] [k] = min (dp[I [j] [K], dp[i-1] [j] [K]); intT = ((1<< s)-1) ^ (J |k); intM1 = st[i] & T, m2 = st[i] &J; dp[I [(J| M1) ^ m2] [k | m2] = min (dp[i] [(J | m1) ^ m2] [k | m2], dp[i-1[j] [K] +c[i]); }} printf ("%d\n", dp[n + m [0][ (1<< s)-1 ] ); } return 0;}
Because there are a lot of useless states, so the memory of the search time is more efficient
#include <bits/stdc++.h>using namespacestd;#definePB Push_back#defineMP Make_pair#defineSe Second#defineFS First#defineLson l,m,rt<<1#defineRson m+1,r,rt<<1|1#definePII pair<int,int>#definell Long LongConst intMAXN = -+ -+5;Const intMaxs =8;Const intINF =100000000;intN, M, s;intc[MAXN], st[MAXN], d[MAXN [1<< Maxs [1<<Maxs];intdpintIintS0,intS1,intS2) { if(i = = m + N)returnS2 = = (1<< s)-1?0: INF; int& ans =d[I [S1] [S2]; if(Ans >=0)returnans; Ans=INF; if(i >= m) ans = DP (i +1, S0, S1, S2); intM0 = st[i] & S0, m1 = st[i] &S1; S0^=M0; S1= (S1 ^ m1) |M0; S2|=M1; Ans= min (ans, c[i] + DP (i +1, S0, S1, S2)); returnans;}intMain () {intx; stringLine ; while(Getline (CIN, line)) {StringStream SS (line); SS>> s >> m >>N; if(s = =0) Break; for(inti =0; I < M + N; i + +) {getline (cin, line); StringStream SS (line); SS>>c[i]; st[i]=0; while(ss >> X) st[i] |= (1<< (X-1 ) ); } memset (d,-1,sizeof(d)); cout<< DP (0, (1<< s)-1,0,0) <<Endl; } return 0;}
UVA 10817Headmaster ' s headache