标签:
4-10,广工校赛,一场坑爹的邂逅。。。。。。
首先,路程坑爹,问了好久路才到什么GUI工学馆。。。。
其次,天气坑爹,怎么老是下雨。。。。
最后,比赛坑爹,本垃圾被坑得不要不要的,为什么题A1小时前和一小时后看的是不一样的,改题面,改样例,恩,你倒不如新增一道题算了;为什么题C无解啊!广工:大家注意,没有这种数据(没有你放出来干*啊)。。。。
题意:略
题解:实质上是贪心模拟题,先从根节点往下走,把根节点的怪都消灭掉之后,在把它的儿子都加进来,最后看有没有打不过的就可以了。
代码怎么写呢?先用dfs从根出发,然后扫到一个有怪物的结点,加进去之后就退出来,不在dfs,从优先队列拿出元素之后,记录这个点有没有全部拿完怪兽,有的dfs这个点就好了。
1 /*zhen hao*/
2 #include <cstdio>
3 #include <cstring>
4 #include <iostream>
5 #include <algorithm>
6 #include <vector>
7 #include <queue>
8 using namespace std;
9
10 typedef pair<int,int> pii;
11 const int maxn = 1e3 + 10;
12 int cnt[maxn], father[maxn];
13 int n, m, k;
14 vector<int> tree[maxn];
15
16 struct Node {
17 int id, d, a;
18 Node(int id=0, int d=0, int a=0) : id(id), d(d), a(a) {}
19 bool operator < (const Node& o) const {
20 return d > o.d;
21 }
22 };
23
24 priority_queue<Node> pq;
25 vector<Node> mon[maxn];
26
27 void dfs(int u, int fa) {
28 father[u] = fa;
29 if (!mon[u].empty()) {
30 for (int i = 0; i < (int)mon[u].size(); i++) pq.push(mon[u][i]);
31 return;
32 }
33 for (int i = 0; i < (int)tree[u].size(); i++) {
34 int v = tree[u][i];
35 if (v == fa) continue;
36 dfs(v, u);
37 }
38 }
39
40 int main() {
41 // freopen("case.in", "r", stdin);
42 int T;
43 cin >> T;
44 while (T--) {
45 scanf("%d%d", &n, &m);
46 for (int i = 0; i < n; i++) tree[i].clear(), mon[i].clear();
47 for (int i = 0; i < n - 1; i++) {
48 int u, v;
49 scanf("%d%d", &u, &v);
50 tree[u].push_back(v);
51 tree[v].push_back(u);
52 }
53 scanf("%d", &k);
54 for (int i = 0; i < m; i++) {
55 int x, y, z;
56 scanf("%d%d%d", &x, &y, &z);
57 mon[x].push_back(Node(x, y, z));
58 }
59
60 while (!pq.empty()) pq.pop();
61
62 dfs(0, -1);
63 memset(cnt, 0, sizeof cnt);
64
65 while (!pq.empty()) {
66 Node p = pq.top(); pq.pop();
67 // cout << p.id << " " << p.d << " " << p.a << " " << pq.size() << endl;
68 if (k <= p.d) { k = -1; break; }
69 k += p.a;
70 int u = p.id;
71 if (++cnt[u] >= (int)mon[u].size()) {
72 for (int i = 0; i < (int)tree[u].size(); i++) {
73 int v = tree[u][i];
74 if (v == father[u]) continue;
75 dfs(v, u);
76 }
77 }
78 }
79 // cout << k << endl;
80 if (k != -1) puts("Oh yes.");
81 else puts("Good Good Study,Day Day Up.");
82 }
83 }
题意:略
题解:暴力水题,枚举首饰和头盔,枚举单手剑即可,dp1[i]表示用了i元钱能够买到最大首饰盒头盔的攻击力,dp2[i]表示用了i元钱能够买到最大的剑的攻击力,然后总结一下最大值即可。
注意两个坑点:第一id == -1 buff == -1buff无效,第二剑只有一把;
1 /*zhen hao*/
2 #include <cstdio>
3 #include <cstring>
4 #include <algorithm>
5 #include <iostream>
6 #include <vector>
7 #include <string>
8 #include <queue>
9 using namespace std;
10
11 struct Node {
12 int mon, atk, id, buff;
13 };
14
15 Node A[110], B[110], C[110], D[110];
16 int dp1[10010], dp2[10010];
17
18 int main() {
19 // freopen("case.in", "r", stdin);
20 int T;
21 cin >> T;
22 while (T--) {
23 int m, a, b, c, d;
24 cin >> m >> a >> b >> c >> d;
25 memset(dp1, 0, sizeof dp1);
26 memset(dp2, 0, sizeof dp2);
27
28 for (int i = 0; i < a; i++) {
29 scanf("%d%d", &A[i].mon, &A[i].atk);
30 dp1[A[i].mon] = max(dp1[A[i].mon], A[i].atk);
31 }
32 for (int i = 0; i < b; i++) {
33 scanf("%d%d%d%d", &B[i].mon, &B[i].atk, &B[i].id, &B[i].buff);
34 dp1[B[i].mon] = max(dp1[B[i].mon], B[i].atk);
35 }
36 for (int i = 0; i < c; i++) {
37 scanf("%d%d", &C[i].mon, &C[i].atk);
38 dp2[C[i].mon] = max(dp2[C[i].mon], C[i].atk);
39 }
40 for (int i = 0; i < d; i++) {
41 scanf("%d%d", &D[i].mon, &D[i].atk);
42 dp2[D[i].mon] = max(dp2[D[i].mon], D[i].atk);
43 }
44
45 for (int i = 0; i < a; i++)
46 for (int j = 0; j < b; j++) {
47 int temp;
48 if (B[j].buff != -1 && B[j].id == i) temp = A[i].atk + B[j].atk + B[j].buff;
49 else temp = A[i].atk + B[j].atk;
50 dp1[A[i].mon + B[j].mon] = max(dp1[A[i].mon + B[j].mon], temp);
51 }
52
53 for (int i = 0; i < c; i++)
54 for (int j = 0; j < i; j++)
55 dp2[C[i].mon + C[j].mon] = max(dp2[C[i].mon + C[j].mon], C[i].atk + C[j].atk);
56
57 for (int i = 1; i <= m; i++) {
58 dp1[i] = max(dp1[i], dp1[i - 1]);
59 dp2[i] = max(dp2[i], dp2[i - 1]);
60 }
61 int ans = 0;
62 for (int i = 0; i <= m; i++) {
63 ans = max(ans, dp1[i] + dp2[m - i]);
64 ans = max(ans, dp1[i]);
65 ans = max(ans, dp2[i]);
66 }
67 cout << ans << endl;
68 }
69 return 0;
70 }
题意:略
题解:连成一个有向图,然后跑dij之后,看最短路有多少条即可。
1 /*zhen hao*/
2 #include <cstdio>
3 #include <cstring>
4 #include <algorithm>
5 #include <iostream>
6 #include <vector>
7 #include <string>
8 #include <queue>
9 using namespace std;
10
11 const int maxn = 1e2 + 10, maxp = 1e4 + 10, inf = 1 << 30, mod = 1e9 + 9;
12 const int dx[] = {0, 0, 1, -1}, dy[] = {1, -1, 0, 0};
13 int head[maxp], dist[maxp], done[maxp], dp[maxp];
14 int n, src, target, tot;
15 int val[maxn][maxn], id[maxn][maxn];
16
17 struct Edge {
18 int v, w, next;
19 Edge(int v = 0, int w = 0, int next = 0) : v(v), w(w), next(next) {}
20 } edges[maxp * 100];
21
22 struct Node {
23 int d, u;
24 Node(int d = 0, int u = 0) : d(d), u(u) {}
25 bool operator < (const Node& o) const {
26 return d > o.d;
27 }
28 };
29
30 void init() {
31 memset(head, -1, sizeof head);
32 tot = 0;
33 }
34
35 void add_edge(int u, int v, int w) {
36 edges[tot] = Edge(v, w, head[u]);
37 head[u] = tot++;
38 }
39
40 void dijkstra() {
41 priority_queue<Node> pq;
42 memset(done, 0, sizeof done);
43 for (int i = src; i <= target; i++) dist[i] = inf;
44 dist[src] = 0;
45 pq.push(Node(0, src));
46 while (!pq.empty()) {
47 Node r = pq.top(); pq.pop();
48 int u = r.u;
49 if (done[u]) continue;
50 done[u] = true;
51 for (int i = head[u]; ~i; i = edges[i].next) {
52 Edge e = edges[i];
53 if (dist[e.v] > dist[u] + e.w) {
54 dist[e.v] = dist[u] + e.w;
55 pq.push(Node(dist[e.v], e.v));
56 }
57 }
58 }
59 }
60
61 void print() {
62 for (int i = src; i <= target; i++) {
63 printf("%d: ", i);
64 for (int j = head[i]; ~j; j = edges[j].next) {
65 printf("(%d %d) ", edges[j].v, edges[j].w);
66 }
67 puts("");
68 }
69 }
70
71 int walk(int u) {
72 if (u == target) return 1;
73 if (dp[u] != -1) return dp[u];
74 int& ret = dp[u];
75 ret = 0;
76 for (int i = head[u]; ~i; i = edges[i].next) {
77 Edge e = edges[i];
78 if (dist[u] + e.w == dist[e.v]) {
79 ret += walk(e.v);
80 if (ret >= mod) ret -= mod;
81 }
82 }
83 return ret;
84 }
85
86 int main() {
87 // freopen("case.in", "r", stdin);
88 int T;
89 cin >> T;
90 while (T--) {
91 scanf("%d", &n);
92 for (int i = 0; i < n; i++)
93 for (int j = 0; j < n; j++) {
94 scanf("%d", &val[i][j]);
95 }
96
97 for (int i = 0, k = n - 1; i < n; i++, k--)
98 for (int j = 0, l = n - 1; j < n - i - 1; j++, l--)
99 val[i][j] += val[l][k];
100
101 src = 0, target = 0;
102 init();
103 for (int i = 0; i < n; i++)
104 for (int j = 0; j < n - i; j++)
105 id[i][j] = target++;
106
107 for (int i = 0; i < n; i++)
108 for (int j = 0; j < n - i; j++) {
109 int u = id[i][j];
110 // cout << i << " " << j << " " << id[i][j] << targetl;
111 for (int k = 0; k < 4; k++) {
112 int ii = i + dx[k], jj = j + dy[k];
113 if (ii >= 0 && ii < n && jj >= 0 && jj < n - ii) {
114 int v = id[ii][jj];
115 add_edge(u, v, val[ii][jj]);
116 }
117 }
118 }
119
120 for (int i = 0; i < n; i++) {
121 int x = id[i][n - i - 1];
122 add_edge(x, target, 0);
123 add_edge(target, x, 0);
124 }
125 if (target >= maxp || tot > maxp * 100) {
126 while (true);
127 }
128
129 // print();
130 dijkstra();
131 memset(dp, -1, sizeof dp);
132 printf("%d\n", walk(src));
133 }
134 return 0;
135 }
题意:略
题解:容斥+dfs枚举子集。不能用位来枚举,因为有个关键的剪枝就是:如果这个数大于le9就不用再继续枚举下去了,这样想想,好像真的很小的复杂度,因为还有个去重,就是如果aj是某个ai的备受,那么就不用管这个aj;挺好的一道题。
1 /*zhen hao*/
2 #include <cstdio>
3 #include <cstring>
4 #include <iostream>
5 #include <algorithm>
6 using namespace std;
7
8 typedef long long ll;
9 const int maxn = 60, con = 1e9;
10 int v[maxn], nv[maxn];
11 int n, cnt, ans;
12
13 int gcd(int a, int b) {
14 if (!b) return a;
15 return gcd(b, a % b);
16 }
17
18 void dfs(int now, int cur, ll LCM) {
19 if (cur >= cnt) {
20 if (now) ans += (con / LCM) * (now & 1 ? -1 : 1);
21 return;
22 }
23 if (LCM > con) return;
24 dfs(now, cur + 1, LCM);
25 if (now) {
26 if (LCM % nv[cur]) LCM *= nv[cur] / gcd(nv[cur], LCM);
27 dfs(now + 1, cur + 1, LCM);
28 } else {
29 dfs(now + 1, cur + 1, nv[cur]);
30 }
31 }
32
33 int main() {
34 // freopen("case.in", "r", stdin);
35 int T;
36 scanf("%d", &T);
37 while (T--) {
38 scanf("%d", &n);
39 for (int i = 0; i < n; i++) scanf("%d", v + i);
40 cnt = 0;
41 sort(v, v + n);
42
43 if (v[0] == 1) {
44 puts("0"); continue;
45 }
46
47 for (int i = 0; i < n; i++) {
48 bool ok = true;
49 for (int j = 0; j < i; j++) if (v[i] % v[j] == 0) ok = false;
50 if (ok) nv[cnt++] = v[i];
51 }
52 ans = con;
53 dfs(0, 0, 1);
54 printf("%lld\n", ans);
55 }
56 return 0;
57 }
标签:
原文地址:http://www.cnblogs.com/zhenhao1/p/5382106.html