状态DP显然可以解,发现T了,不知道优化后能不能过。
然后发现费用流可以解。trick是对need拆解成need/K, need%K两种情况讨论。
1 /* 4312 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <algorithm> 12 #include <cstdio> 13 #include <cmath> 14 #include <ctime> 15 #include <cstring> 16 #include <climits> 17 #include <cctype> 18 #include <cassert> 19 #include <functional> 20 #include <iterator> 21 #include <iomanip> 22 using namespace std; 23 //#pragma comment(linker,"/STACK:102400000,1024000") 24 25 #define sti set<int> 26 #define stpii set<pair<int, int> > 27 #define mpii map<int,int> 28 #define vi vector<int> 29 #define pii pair<int,int> 30 #define vpii vector<pair<int,int> > 31 #define rep(i, a, n) for (int i=a;i<n;++i) 32 #define per(i, a, n) for (int i=n-1;i>=a;--i) 33 #define clr clear 34 #define pb push_back 35 #define mp make_pair 36 #define fir first 37 #define sec second 38 #define all(x) (x).begin(),(x).end() 39 #define SZ(x) ((int)(x).size()) 40 #define lson l, mid, rt<<1 41 #define rson mid+1, r, rt<<1|1 42 43 typedef struct { 44 int v, w, f, nxt; 45 } edge_t; 46 47 const int INF = 0x3f3f3f3f; 48 const int maxv = 30; 49 const int maxe = 1e5+5; 50 int need[maxv]; 51 int a[15][15]; 52 int head[maxv], l; 53 edge_t E[maxe]; 54 int dis[maxv]; 55 int pre[maxv], ID[maxv]; 56 bool visit[maxv]; 57 int cost, flow; 58 int n, m, K; 59 const int ed = maxv - 1; 60 const int st = maxv - 2; 61 62 void init() { 63 l = 0; 64 memset(head, -1, sizeof(head)); 65 } 66 67 void addEdge(int u, int v, int w, int c) { 68 E[l].v = v; 69 E[l].w = w; 70 E[l].f = c; 71 E[l].nxt = head[u]; 72 head[u] = l++; 73 74 E[l].v = u; 75 E[l].w = -w; 76 E[l].f = 0; 77 E[l].nxt = head[v]; 78 head[v] = l++; 79 } 80 81 bool bfs() { 82 queue<int> Q; 83 int u, v, k; 84 85 memset(dis, INF, sizeof(dis)); 86 memset(visit, false, sizeof(visit)); 87 Q.push(st); 88 visit[st] = true; 89 dis[st] = 0; 90 91 while (!Q.empty()) { 92 u = Q.front(); 93 Q.pop(); 94 visit[u] = false; 95 for (k=head[u]; k!=-1; k=E[k].nxt) { 96 v = E[k].v; 97 if (E[k].f && dis[v]>dis[u]+E[k].w) { 98 dis[v] = dis[u] + E[k].w; 99 pre[v] = u; 100 ID[v] = k; 101 if (!visit[v]) { 102 visit[v] = true; 103 Q.push(v); 104 } 105 } 106 } 107 } 108 109 return dis[ed]==INF; 110 } 111 112 void MCMF() { 113 int u, v, k; 114 int tmp; 115 116 flow = 0, cost = 0; 117 118 while (1) { 119 if (bfs()) 120 break; 121 122 tmp = INF; 123 for (v=ed, u=pre[v]; v!=st; v=u, u=pre[v]) { 124 k = ID[v]; 125 tmp = min(tmp, E[k].f); 126 } 127 128 for (v=ed, u=pre[v]; v!=st; v=u, u=pre[v]) { 129 k = ID[v]; 130 E[k].f -= tmp; 131 E[k^1].f += tmp; 132 } 133 134 flow += tmp; 135 cost += tmp * dis[ed]; 136 } 137 } 138 139 void solve() { 140 int tot = 0, tmp; 141 142 init(); 143 rep(i, 0, m) 144 addEdge(st, i+n, 0, 1); 145 146 rep(i, 0, n) { 147 tot += need[i]; 148 rep(j, 0, m) { 149 if (a[i][j]) 150 addEdge(j+n, i, 0, 1); 151 } 152 tmp = need[i] / K; 153 if (tmp) { 154 addEdge(i, ed, -K, tmp); 155 } 156 tmp = need[i] % K; 157 if (tmp > 1) { 158 addEdge(i, ed, -tmp, 1); 159 } 160 } 161 162 MCMF(); 163 164 cost = -cost; 165 if (cost+m-flow < tot) 166 puts("NO"); 167 else 168 puts("YES"); 169 } 170 171 int main() { 172 ios::sync_with_stdio(false); 173 #ifndef ONLINE_JUDGE 174 freopen("data.in", "r", stdin); 175 freopen("data.out", "w", stdout); 176 #endif 177 178 int t; 179 180 scanf("%d", &t); 181 rep(tt, 1, t+1) { 182 scanf("%d %d %d", &m, &n, &K); 183 rep(i, 0, n) 184 scanf("%d", &need[i]); 185 rep(i, 0, n) 186 rep(j, 0, m) 187 scanf("%d", &a[i][j]); 188 printf("Case #%d: ", tt); 189 solve(); 190 } 191 192 #ifndef ONLINE_JUDGE 193 printf("time = %d.\n", (int)clock()); 194 #endif 195 196 return 0; 197 }
数据发生器。
1 from copy import deepcopy 2 from random import randint, shuffle 3 import shutil 4 import string 5 6 7 def GenDataIn(): 8 with open("data.in", "w") as fout: 9 t = 50 10 bound = 10**18 11 fout.write("%d\n" % (t)) 12 for tt in xrange(t): 13 m = randint(1, 13) 14 n = randint(1, 13) 15 k = randint(2, 10) 16 fout.write("%d %d %d\n" % (m, n, k)) 17 L = [] 18 for i in xrange(n): 19 x = randint(1, 20) 20 L.append(x) 21 fout.write(" ".join(map(str, L)) + "\n") 22 for i in xrange(n): 23 L = [] 24 for j in xrange(m): 25 x = randint(0, 1) 26 L.append(x) 27 fout.write(" ".join(map(str, L)) + "\n") 28 29 30 def MovDataIn(): 31 desFileName = "F:\eclipse_prj\workspace\hdoj\data.in" 32 shutil.copyfile("data.in", desFileName) 33 34 35 if __name__ == "__main__": 36 GenDataIn() 37 MovDataIn()