【HDOJ】3957 Street Fighter

一定要注意审题啊,题目说的是选出做少的英雄打败其余处在任何模式下的英雄。
共有Sigma(num of model)个方案,每个方案有Sigma(num of model)+n个决策。
挺不错的一道精确覆盖的题目,最近发现精确覆盖很有意思。

  1 /* 3957 */
  2 #include <iostream>
  3 #include <string>
  4 #include <map>
  5 #include <queue>
  6 #include <set>
  7 #include <stack>
  8 #include <vector>
  9 #include <deque>
 10 #include <algorithm>
 11 #include <cstdio>
 12 #include <cmath>
 13 #include <ctime>
 14 #include <cstring>
 15 #include <climits>
 16 #include <cctype>
 17 #include <cassert>
 18 #include <functional>
 19 #include <iterator>
 20 #include <iomanip>
 21 using namespace std;
 22 //#pragma comment(linker,"/STACK:102400000,1024000")
 23
 24 #define sti                set<int>
 25 #define stpii            set<pair<int, int> >
 26 #define mpii            map<int,int>
 27 #define vi                vector<int>
 28 #define pii                pair<int,int>
 29 #define vpii            vector<pair<int,int> >
 30 #define rep(i, a, n)     for (int i=a;i<n;++i)
 31 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 32 #define clr                clear
 33 #define pb                 push_back
 34 #define mp                 make_pair
 35 #define fir                first
 36 #define sec                second
 37 #define all(x)             (x).begin(),(x).end()
 38 #define SZ(x)             ((int)(x).size())
 39 #define lson            l, mid, rt<<1
 40 #define rson            mid+1, r, rt<<1|1
 41
 42 typedef struct {
 43     static const int maxc = 30*3+5;
 44     static const int maxr = 60;
 45     static const int maxn = 60*60+5;
 46
 47     int nmodel;
 48     int n, sz;
 49     int S[maxc];
 50
 51     int col[maxn];
 52     int L[maxn], R[maxn], U[maxn], D[maxn];
 53     bool visit[maxc];
 54
 55     int ansd;
 56
 57     void init(int nmodel_, int n_) {
 58         ansd = INT_MAX;
 59         n = n_;
 60         nmodel = nmodel_;
 61
 62         rep(i, 0, n+1) {
 63             L[i] = i - 1;
 64             R[i] = i + 1;
 65             U[i] = i;
 66             D[i] = i;
 67             col[i] = i;
 68         }
 69         L[0] = n;
 70         R[n] = 0;
 71
 72         sz = n + 1;
 73         memset(S, 0, sizeof(S));
 74     }
 75
 76     void addRow(vi columns) {
 77         int first = sz;
 78         int size = SZ(columns);
 79
 80         rep(i, 0, size) {
 81             int c = columns[i];
 82
 83             L[sz] = sz - 1;
 84             R[sz] = sz + 1;
 85
 86             D[sz] = c;
 87             U[sz] = U[c];
 88             D[U[c]] = sz;
 89             U[c] = sz;
 90
 91             col[sz] = c;
 92
 93             ++S[c];
 94             ++sz;
 95         }
 96
 97         L[first] = sz - 1;
 98         R[sz - 1] = first;
 99     }
100
101     void remove(int c) {
102         L[R[c]] = L[c];
103         R[L[c]] = R[c];
104         for (int i=D[c]; i!=c; i=D[i]) {
105             for (int j=R[i]; j!=i; j=R[j]) {
106                 U[D[j]] = U[j];
107                 D[U[j]] = D[j];
108                 --S[col[j]];
109             }
110         }
111     }
112
113     void restore(int c) {
114         L[R[c]] = c;
115         R[L[c]] = c;
116         for (int i=D[c]; i!=c; i=D[i]) {
117             for (int j=R[i]; j!=i; j=R[j]) {
118                 U[D[j]] = j;
119                 D[U[j]] = j;
120                 ++S[col[j]];
121             }
122         }
123     }
124
125     void remove_col(int c) {
126         for (int i=D[c]; i!=c; i=D[i]) {
127             L[R[i]] = L[i];
128             R[L[i]] = R[i];
129         }
130     }
131
132     void restore_col(int c) {
133         for (int i=D[c]; i!=c; i=D[i]) {
134             L[R[i]] = i;
135             R[L[i]] = i;
136         }
137     }
138
139     int H() {
140         // return 0;
141         int ret = 0;
142
143         memset(visit, false, sizeof(visit));
144         for (int c=R[0]; c!=0&&c<=nmodel; c=R[c]) {
145             if (visit[c])
146                 continue;
147             ++ret;
148             visit[c] = true;
149             for (int i=D[c]; i!=c; i=D[i]) {
150                 for (int j=R[i]; j!=i; j=R[j])
151                     visit[col[j]] = true;
152             }
153         }
154
155         return ret;
156     }
157
158     void dfs(int d) {
159         if (R[0]==0 || R[0]>nmodel) {
160             ansd = min(ansd, d);
161             return ;
162         }
163
164         int delta = H();
165
166         if (d+delta >= ansd)
167             return ;
168
169         int c = R[0];
170         for (int i=R[0]; i!=0&&i<=nmodel; i=R[i]) {
171             if (S[i] < S[c])
172                 c = i;
173         }
174
175         for (int i=D[c]; i!=c; i=D[i]) {
176             remove_col(i);
177             for (int j=R[i]; j!=i; j=R[j]) {
178                 if (col[j] <= nmodel)
179                     remove_col(j);
180             }
181             for (int j=R[i]; j!=i; j=R[j]) {
182                 if (col[j] > nmodel)
183                     remove(col[j]);
184             }
185             dfs(d + 1);
186             for (int j=L[i]; j!=i; j=L[j]) {
187                 if (col[j] > nmodel)
188                     restore(col[j]);
189             }
190             for (int j=L[i]; j!=i; j=L[j]) {
191                 if (col[j] <= nmodel)
192                     restore_col(j);
193             }
194             restore_col(i);
195         }
196     }
197
198     void solve() {
199         ansd = INT_MAX;
200         dfs(0);
201     }
202
203 } DLX;
204
205 typedef struct {
206     int m, k[2];
207     pii p[2][11];
208 } hero_t;
209
210 DLX solver;
211 int ID[30][2];
212 int nmodel, n;
213 hero_t hero[30];
214
215 void solve() {
216     solver.init(nmodel, n+nmodel);
217
218     rep(i, 0, n) {
219         rep(j, 0, hero[i].m) {
220             // each model has a plan
221             vi columns;
222             // cover i-th hero
223             columns.pb(nmodel+i+1);
224             // cover 0-th plan
225             columns.pb(ID[i][0]);
226             // may cover 1-th plan
227             if (hero[i].m == 2)
228                 columns.pb(ID[i][1]);
229             rep(k, 0, hero[i].k[j]) {
230                 int role_id = hero[i].p[j][k].fir;
231                 int model_id = hero[i].p[j][k].sec;
232                 columns.pb(ID[role_id][model_id]);
233             }
234
235             solver.addRow(columns);
236         }
237     }
238
239     solver.solve();
240
241     printf("%d\n", solver.ansd);
242 }
243
244 int main() {
245     ios::sync_with_stdio(false);
246     #ifndef ONLINE_JUDGE
247         freopen("data.in", "r", stdin);
248         freopen("data.out", "w", stdout);
249     #endif
250
251     int t;
252
253     scanf("%d", &t);
254     rep(tt, 1, t+1) {
255         scanf("%d", &n);
256         nmodel = 0;
257         rep(i, 0, n) {
258             scanf("%d", &hero[i].m);
259             rep(j, 0, hero[i].m) {
260                 scanf("%d", &hero[i].k[j]);
261                 rep(k, 0, hero[i].k[j])
262                     scanf("%d %d", &hero[i].p[j][k].fir, &hero[i].p[j][k].sec);
263                 ID[i][j] = ++nmodel;
264             }
265         }
266         printf("Case %d: ", tt);
267         solve();
268     }
269
270     #ifndef ONLINE_JUDGE
271         printf("time = %d.\n", (int)clock());
272     #endif
273
274     return 0;
275 }
时间: 2024-10-25 00:40:34

【HDOJ】3957 Street Fighter的相关文章

【HDOJ】4956 Poor Hanamichi

基本数学题一道,看错位数,当成大数减做了,而且还把方向看反了.所求为最接近l的值. 1 #include <cstdio> 2 3 int f(__int64 x) { 4 int i, sum; 5 6 i = sum = 0; 7 while (x) { 8 if (i & 1) 9 sum -= x%10; 10 else 11 sum += x%10; 12 ++i; 13 x/=10; 14 } 15 return sum; 16 } 17 18 int main() { 1

【HDOJ】1099 Lottery

题意超难懂,实则一道概率论的题目.求P(n).P(n) = n*(1+1/2+1/3+1/4+...+1/n).结果如果可以除尽则表示为整数,否则表示为假分数. 1 #include <cstdio> 2 #include <cstring> 3 4 #define MAXN 25 5 6 __int64 buf[MAXN]; 7 8 __int64 gcd(__int64 a, __int64 b) { 9 if (b == 0) return a; 10 else return

【HDOJ】2844 Coins

完全背包. 1 #include <stdio.h> 2 #include <string.h> 3 4 int a[105], c[105]; 5 int n, m; 6 int dp[100005]; 7 8 int mymax(int a, int b) { 9 return a>b ? a:b; 10 } 11 12 void CompletePack(int c) { 13 int i; 14 15 for (i=c; i<=m; ++i) 16 dp[i]

【HDOJ】3509 Buge&#39;s Fibonacci Number Problem

快速矩阵幂,系数矩阵由多个二项分布组成.第1列是(0,(a+b)^k)第2列是(0,(a+b)^(k-1),0)第3列是(0,(a+b)^(k-2),0,0)以此类推. 1 /* 3509 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #incl

【HDOJ】1818 It&#39;s not a Bug, It&#39;s a Feature!

状态压缩+优先级bfs. 1 /* 1818 */ 2 #include <iostream> 3 #include <queue> 4 #include <cstdio> 5 #include <cstring> 6 #include <cstdlib> 7 #include <algorithm> 8 using namespace std; 9 10 #define MAXM 105 11 12 typedef struct {

【HDOJ】2424 Gary&#39;s Calculator

大数乘法加法,直接java A了. 1 import java.util.Scanner; 2 import java.math.BigInteger; 3 4 public class Main { 5 public static void main(String[] args) { 6 Scanner cin = new Scanner(System.in); 7 int n; 8 int i, j, k, tmp; 9 int top; 10 boolean flag; 11 int t

【HDOJ】2425 Hiking Trip

优先级队列+BFS. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 7 #define MAXN 25 8 9 typedef struct node_st { 10 int x, y, t; 11 node_st() {} 12 node_st(int xx, int yy, int tt)

【HDOJ】1686 Oulipo

kmp算法. 1 #include <cstdio> 2 #include <cstring> 3 4 char src[10005], des[1000005]; 5 int next[10005], total; 6 7 void kmp(char des[], char src[]){ 8 int ld = strlen(des); 9 int ls = strlen(src); 10 int i, j; 11 12 total = i = j = 0; 13 while (

【HDOJ】2795 Billboard

线段树.注意h范围(小于等于n). 1 #include <stdio.h> 2 #include <string.h> 3 4 #define MAXN 200005 5 #define lson l, mid, rt<<1 6 #define rson mid+1, r, rt<<1|1 7 #define mymax(x, y) (x>y) ? x:y 8 9 int nums[MAXN<<2]; 10 int h, w; 11 12