[Compression Algorithm] state DP

DP is a state of compression What?

A: The use bit arithmetic (addition, subtraction bit computing than almost!) To record the state, and dynamic programming.

What applies to the problem?

A: Data smaller; you can not use a simple algorithm to solve.

 

example:

Title Description

Candy shop owner, a total of M flavors of candy to sell. For convenience of description, we will M flavors No. 1 ~ M.
Steve wants to taste the candy of all flavors. Unfortunately, the boss does not sell candy alone, but K pieces of a pack of whole package for sale.
Fortunately, the taste of which are noted K pieces of candy on candy wrappers, so Bob can know candy flavors in every pack before you buy.
Given N packet of sweets, you calculate Xiao Ming to buy at least a few packs, you can enjoy all the taste of candy.

Entry

The first line contains three integers N, M and K.
Next N lines and K an integer of T1, T2, ..., TK, representing a packet of candy taste.
1 <= N <= 100,1 < = M <= 20,1 <= K <= 20,1 <= Ti <= M.

Export

An integer that represents the answer. If Bob can not taste all the flavors, output -1.

Sample input 

6 5 3
1 1 2
1 2 3
1 1 3
2 3 5
5 4 2
5 1 2

Sample Output

2

Data is small, it is suitable for compression DP state.

Ideas are as follows:

With binary ones and zeros to represent the presence or absence of certain types of candy. For example, according to the above examples, a total of five kinds of candy. The second line 112 is 00,011, the third line 123 is 00 111, the last line 512 is 10011 ...

Then we use dp storage array in these states.

int dp[1<<m];

Are initialized to -1 for each line read, it will assign a corresponding element, representing buy a pack can buy these types of candies.

AC code is as follows:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 int main() {
 5     int n, m, k,s,ss;
 6     cin >> n >> m >> k;
 7     int dp[1 << 20];
 8     int goods[100];
 9     memset(dp, -1, sizeof(dp));
10     for(int j=0;j<n;j++) {
11         ss = 0;
12         for (int i = 0; i < k; i++) {
13             cin >> s;
14             ss |= (1 << (s - 1));
15         }
16         goods[j] = ss;
17         dp[ss] = 1;
18     }
19     for (int i = 0; i < n; i++) {
20         for (int j = 0; j < (1 << m); j++) {
21             if (dp[j] == -1) continue;
22             if (dp[j | goods[i]] == -1)
23                 dp[j | goods[i]] = dp[j] + dp[goods[i]];
24             else
25                 dp[j | goods[i]] = min(dp[j] + dp[goods[i]], dp[j | goods[i]]);
26         }
27     }
28     cout << dp[(1 << m) - 1];
29 }

 

Guess you like

Origin www.cnblogs.com/zyyz1126/p/12377491.html