5.4 ~ 5.6 刷题记录
bzoj 1096 斜率优化水题,( 闭着眼做)
/************************************************************** Problem: 1096 User: BriMon Language: C++ Result: Accepted Time:2576 ms Memory:55980 kb ****************************************************************/ #include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; #define maxn 1000010 #define int long long int n, x[maxn], p[maxn], c[maxn]; int sum[maxn], s[maxn]; int f[maxn]; inline int G(int i) { return x[i]; } inline int X(int i) { return sum[i]; } inline int D(int i) { return c[i] - s[i] + x[i] * sum[i]; } inline int Y(int i) { return f[i] + s[i]; } inline double slope(int a, int b) { return ((double)(Y(b) - Y(a)) / (double)(X(b) - X(a))); } int q[maxn], l, r; signed main() { cin >> n; for (int i = 1; i <= n; i++){ scanf("%lld%lld%lld", &x[i], &p[i], &c[i]); sum[i] = sum[i-1] + p[i]; s[i] = s[i-1] + x[i] * p[i]; f[i] = 0x7f7f7f7f; } for (int i = 1; i <= n; i++){ while (l < r && slope(q[l], q[l+1]) < G(i)) l++; int j = q[l]; f[i] = Y(j) - G(i) * X(j) + D(i); while(l < r && slope(q[r-1], q[r]) > slope(q[r-1], i)) r--; q[++r] = i; } cout << f[n]; return 0; }
bzoj 1003 DP加SPFA调了一下午(我太弱了)
/************************************************************** Problem: 1003 User: BriMon Language: C++ Result: Accepted Time:44 ms Memory:1384 kb ****************************************************************/ #include <iostream> #include <cstdio> #include <algorithm> #include <queue> #include <cstring> using namespace std; int n, m, c, e, d; struct edge { int nxt; int to; int val; }ed[4000]; int head[25], cnt; void add(int x, int y, int z) { cnt++; ed[cnt].nxt = head[x]; ed[cnt].to = y; ed[cnt].val = z; head[x] = cnt; } int f[101][101], dp[101]; bool cant[25][105]; bool flag[21]; int dis[21]; bool ex[21]; queue <int> q; int SPFA() { memset(dis, 0x3f, sizeof dis); memset(ex, 0, sizeof ex); dis[1] = 0; ex[1] = 1; while(!q.empty()) q.pop(); q.push(1); while(!q.empty()) { int t = q.front(); q.pop(); ex[t] = 0; for (int i = head[t] ; i ; i = ed[i].nxt) { int to = ed[i].to, v = ed[i].val; if(dis[to] > dis[t] + v and !flag[to]) { dis[to] = dis[t] + v; if(!ex[to]) { ex[to] = 1; q.push(to); } } } } // printf("%d\n", dis[m]); return dis[m]; } int main() { cin >> n >> m >> c >> e; for (int i = 1 ; i <= e ; i ++) { int x, y, z; scanf("%d%d%d", &x, &y, &z); add(x, y, z); add(y, x, z); } cin >> d; for (int i = 1 ; i <= d ; i ++) { int x, y, z; scanf("%d%d%d", &x, &y, &z); for (int j = y ; j <= z ; j ++) { cant[x][j] = 1; } } for (int i = 1 ; i <= n ; i++) { for (int j = i ; j <= n ; j++) { memset(flag, 0, sizeof flag); for (int k = 1 ; k <= m ; k ++) { for(int l = i ; l <= j ; l ++) { flag[k] |= cant[k][l]; } } f[i][j] = SPFA(); // cout << f[i][j] << endl; } } memset(dp, 0x7f, sizeof dp); for (int i = 1 ; i <= n ; i ++){ for (int j = i ; j <= n ; j ++){ if(f[i][j] < 0x3f3f3f3f) f[i][j] *= (j - i + 1); } } for (int i = 1 ; i <= n ; i ++) dp[i] = f[1][i]; for (int i = 2 ; i <= n ; i++) { for (int j = 1 ; j < i ; j ++) { dp[i] = min(dp[i], dp[j] + f[j+1][i] + c); } } cout << dp[n]; return 0; }
Luogu 2756 作为机房里唯一一个还不会网络流的蒟蒻,对着这道模板题瑟瑟发抖
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <queue> using namespace std; int n, m; struct edge { int nxt; int to; int flow; }ed[5005]; int head[201], cnt = 1; void add(int x, int y, int z) { cnt++, ed[cnt].nxt = head[x], ed[cnt].to = y, ed[cnt].flow = z, head[x] = cnt; cnt++, ed[cnt].nxt = head[y], ed[cnt].to = x, ed[cnt].flow = 0, head[y] = cnt; } int S = 0, T = n + 1; int d[205]; queue <int> q; bool bfs(){ memset(d, 0, sizeof d); while(!q.empty()) q.pop(); q.push(S); d[S] = 1; while (!q.empty()) { int x = q.front();q.pop(); for (int i = head[x] ; i ; i = ed[i].nxt) { int to = ed[i].to; if(!ed[i].flow || d[to]) continue; q.push(to); d[to] = d[x] + 1; if (to == T) return 1; } } return 0; } int Dinic(int x, int flow){ if(x == T) return flow; int rest = flow, k; for (int i = head[x] ; i and rest; i = ed[i].nxt) { int to = ed[i].to; if(ed[i].flow and d[to] == d[x] + 1) { k = Dinic(to, min(rest, ed[i].flow)); if (!k) d[to] = 0; ed[i].flow -= k; ed[i ^ 1].flow += k; rest -= k; } } return flow - rest; } int ans; int main() { cin >> m >> n; int x, y; T = n + 1; for (int i = 1 ; i <= m ; i ++) add(S, i, 1); for (int i = m + 1 ; i <= n ; i++) add(i, T, 1); while(scanf("%d%d", &x, &y) != EOF and x != -1 and y != -1) { add(x, y, 1); } int flow = 0; while (bfs()) { while (flow = Dinic(S, 1 << 29)) ans += flow; } if(!ans) { puts("No Solution"); return 0; } cout << ans << endl; for (int i = 2 ; i <= cnt ; i += 2) { if(ed[i].to != S and ed[i ^ 1].to != S and ed[i].to != T and ed[i ^ 1].to != S and ed[i ^ 1].flow != 0) { printf("%d %d\n", ed[i ^ 1].to, ed[i].to); } } return 0; }
bzoj 1022 nim裸题, 虽然不会博弈
/************************************************************** Problem: 1022 User: BriMon Language: C++ Result: Accepted Time:100 ms Memory:1288 kb ****************************************************************/ #include <iostream> #include <cstdio> #include <cstring> using namespace std; int T; int ans, n, sum; int main() { cin >> T; while (T--){ cin >> n; ans = 0; sum = 0; for (int i = 1 ; i <= n ; i ++){ int a; scanf("%d", &a); ans ^= a; sum += a; } if(sum == n){ if (sum & 1) puts("Brother"); else puts("John"); continue; } if (ans){ puts("John"); } else puts("Brother"); } return 0; }