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;
}
zZhBr

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
", 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;
}
zZhBr

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
", ed[i ^ 1].to, ed[i].to);
        }
    }
    return 0;
    
}
zZhBr

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;
}
zZhBr
原文地址:https://www.cnblogs.com/BriMon/p/8992444.html