列表

详情


NC202120. Blood Pressure Game

描述

1Gugulu, a JBer, who was an ACMer one year ago, comes to Shanghai University taking part in the International Collegiate Programming Contest again. However, every time when Gugulu came to Shanghai University, he always got an Iron Medal and would consider this competition JB-like. To release his pain, Gugulu would go to the Shanghai Disneyland Park to have fun in taking the Roller Coaster. Gugulu loves the feeling with high-level blood pressure so much which makes him feel as a happy flappy bird who forgets all the Wrong Answers and Time Limit Exceededs etc.

We can regard the path of the Roller Coaster as a list of turning points with different heights which can be represented as an array of size , and Gugulu's final blood pressure after the game of the Roller Coaster is counted as the sum of all absolute values of the differences between the pairs of adjacent array numbers, i.e. .

Gugulu always got Iron Medals and is always getting Iron Medals, which makes him keep taking the Roller Coaster over and over again. However, as playing more games, his threshold on the value of blood pressure which can make himself happy is keeping increasing. As a result, the Roller Coaster of Shanghai Disneyland Park can hardly meet Gugulu's need anymore.

Therefore, Gugulu decides to add a set of m extra turning points in any order into this path, however, to consider about the reality on the distance of the original path, he can add at most one turning point into any original position between any two original elements in the array (and at most one in the head, at most one in the tail). Gugulu wants to make his blood pressure as high as possible, and he wants to know how much his blood can reach at most when he has added nextra Roller Coaster turning points into the path.

You, another JBer, are sure that Gugulu is clever enough to get the highest blood pressure as he can. It is very important for you to calculate the exact numbers to make an appointment with a proper cardiologist in advance to save Gugulu's life. You must solve this problem! Gugulu's blood pressure is becoming out of the control!

输入描述

The first line of the input gives the number of test cases,  ().  test cases follow.
For each test case, the first line contains two integers, () and ()
Then, in second line, there are integers , denoting the original Roller Coaster turning points. Then, in the third line, there are integers , denoting the addition Roller Coaster turning points to be added.
As it is an exciting Roller Coaster, it is guaranteed that all integers in the two arrays are pairwise different.
There are at most test cases whose is more than .

输出描述

For each test case, output three lines. The first line contains "Case #x:", where  is the test case number (starting from ). In the second line, there should be  integers which represent how much Gugulu's blood pressure could reach if he has added {1, 2, 3, …, m} extra Roller Coaster turning points into the path. In the third line, there should be  integers which represent the heights of the final Roller Coaster path if he has added all  extra  turning points. If there are several solutions, output any of them.

示例1

输入:

6
2 3
5 11
10 3 1
4 1
1 2 3 4
5
4 2
1 2 3 4
5 6
4 5
1 2 3 4
5 6 7 8 9
4 4
10 50 3 6
1 9 23 5
4 2
10 50 3 6
9 23

输出:

Case #1:
16 22 27 
10 5 1 11 3 
Case #2:
9 
1 5 2 3 4 
Case #3:
11 15 
1 6 2 5 3 4 
Case #4:
17 27 33 38 39 
5 1 9 2 8 3 7 4 6 
Case #5:
124 142 147 150 
5 10 1 50 3 23 6 9 
Case #6:
124 127 
10 50 3 23 6 9

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 9601ms, 内存消耗: 24384K, 提交时间: 2020-03-09 11:27:54

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define pb push_back
#define sz(a) ((int)a.size())
const int maxn = 2e3 + 5;
const ll inf = 1ll << 60;

template<class ll>
struct Dinic{

    struct Edge{ int v, rev; ll cap, cot; };
    vector<Edge> G[maxn];
    ll dis[maxn];
    int cur[maxn], vis[maxn], n, sp, tp;
    void init(int nn){

        n = nn;
        for(int i = 1; i <= n; ++i) G[i].clear();
    }
    void add(int u, int v, ll cap, ll cot){

        G[u].pb({v, sz(G[v]), cap, cot});
        G[v].pb({u, sz(G[u]) - 1, 0, -cot});
    }
    int bfs(){

        queue<int> q;
        for(int i = 1; i <= n; ++i) dis[i] = inf, vis[i] = 0;
        dis[sp] = 0, q.push(sp), vis[sp] = 1;
        while(!q.empty()){

            int u = q.front(); q.pop(); vis[u] = 0;
            for(Edge &e : G[u]){

                if(e.cap && dis[e.v] > dis[u] + e.cot){

                    dis[e.v] = dis[u] + e.cot;
                    if(!vis[e.v]) q.push(e.v), vis[e.v] = 1;
                }
            }
        }
        return dis[tp] != inf;
    }
    ll dfs(int u, ll flow){

        if(u == tp || !flow) return flow;
        ll ret = 0, tmp; vis[u] = 1;
        for(int &i = cur[u]; i < sz(G[u]); ++i){

            Edge &e = G[u][i];
            if(!vis[e.v] && dis[e.v] == dis[u] + e.cot && (tmp = dfs(e.v, min(e.cap, flow - ret)))){

                ret += tmp, e.cap -= tmp, G[e.v][e.rev].cap += tmp;
                if(ret == flow) { vis[u] = 0; return ret; }
            }
        }
        if(!ret) vis[u] = 1;
        return ret;
    }
    pair<ll, ll> solve(int s, int t, ll ans[]){

        sp = s, tp = t;
        ll mf = 0, mc = 0;
        while(bfs()){

            for(int i = 1; i <= n; ++i) cur[i] = 0;
            ll tmp = dfs(sp, inf);
            for(int i = 1; i <= tmp; ++i) ans[i + mf] = ans[i + mf - 1] + dis[tp];
            mf += tmp, mc += tmp * dis[tp];
        }
        return {mf, mc};
    }
};

Dinic<ll> dn;
ll ans[maxn];
int a[maxn], b[maxn];
int n, m;

int main(){
 
    ios::sync_with_stdio(0); cin.tie(0);
    int t, cas = 0; cin >> t;
    while(t--){

        cin >> n >> m;
        for(int i = 1; i <= n; ++i) cin >> a[i];
        for(int i = 1; i <= m; ++i) cin >> b[i];
        cout << "Case #" << ++cas << ":\n";
        ll base = 0;
        for(int i = 1; i < n; ++i) base += abs(a[i] - a[i + 1]);
        int S = m + n + 2, T = S + 1;
        dn.init(T);
        for(int i = 1; i <= m; ++i) dn.add(S, i, 1, 0);
        for(int i = 1; i <= n + 1; ++i) dn.add(m + i, T, 1, 0);
        for(int i = 1; i <= m; ++i){

            dn.add(i, m + 1, 1, -abs(b[i] - a[1]));
            dn.add(i, m + n + 1, 1, -abs(b[i] - a[n]));
            for(int j = 2; j <= n; ++j){

                int dt = abs(b[i] - a[j - 1]) + abs(b[i] - a[j]) -abs(a[j] - a[j - 1]);
                dn.add(i, m + j, 1, -dt);
            }
        }
        dn.solve(S, T, ans);
        for(int i = 1; i <= m; ++i) cout << base - ans[i] << " ";
        cout << "\n";
        for(int i = 1; i <= n + 1; ++i){

            int p = 0;
            for(auto &e : dn.G[m + i]){

                if(e.v == T || !e.cap) continue;
                p = e.v; break;
            }
            if(p) cout << b[p] << " ";
            if(i <= n) cout << a[i] << " ";
        }
        cout << "\n";
    }
    return 0;
}

C++(clang++ 11.0.1) 解法, 执行用时: 5199ms, 内存消耗: 17668K, 提交时间: 2022-11-25 09:34:16

#include<bits/stdc++.h>
#define ls i<<1
#define rs i<<1|1
#define fi first
#define se second
#define min amin
#define max amax
#define pb push_back
using namespace std;
using ll=long long;
using pii=array<int,2>;
constexpr int N=610;
constexpr int inf=1E9;
constexpr int p=998244353;
int qpow(int x,int n=p-2){int y=1;for(;n;n>>=1,x=1LL*x*x%p)if(n&1)y=1LL*y*x%p;return y;}
template<typename T=int>T read(){T x;cin>>x;return x;}
template<typename U,typename V>U min(U x,V y){return x<y?x:y;}
template<typename U,typename V>U max(U x,V y){return x>y?x:y;}
template<typename U,typename...V>U min(U x,V...y){return min(x,min(y...));}
template<typename U,typename...V>U max(U x,V...y){return max(x,max(y...));}
template<typename U,typename V>bool cmin(U &x,V y){return x>y?x=y,true:false;}
template<typename U,typename V>bool cmax(U &x,V y){return x<y?x=y,true:false;}

int n,m,y,z;
int a[N],b[N],c[N],dis[N<<1],pre[N<<1];
vector<array<int,4>>to[N<<1];
queue<int>q;
bool tag[N<<1];
void add(int u,int v,int w)
{
    int l=to[u].size(),r=to[v].size();
    to[u].pb({v,r,w,1});
    to[v].pb({u,l,-w,0});
}
void push(int x,int d,int y)
{
    if(cmax(dis[x],d))
    {
        pre[x]=y;
        if(!tag[x])q.push(x),tag[x]=1;
    }
}
void calc(int x)
{
    for(auto &[t,i,d,w]:to[x])if(w)
    {
        if(t^z)cout<<b[t]<<' ';
        break;
    }
}
void solve()
{
    n=read(),m=read(),y=n+m+2,z=y+1;
    for(int i=1;i<=z;++i)to[i].clear();
    ll ans=0;
    for(int i=1;i<=n;++i)
    {
        cin>>a[i];
        ans+=c[i]=abs(a[i]-a[i-1]);
        add(m+i,z,0);
    }
    ans-=c[1];
    add(y-1,z,0);
    for(int i=1;i<=m;++i)
    {
        cin>>b[i];
        add(y,i,0);
        add(i,m+1,abs(b[i]-a[1]));
        add(i,y-1,abs(b[i]-a[n]));
        for(int j=2;j<=n;++j)add(i,m+j,abs(b[i]-a[j-1])+abs(b[i]-a[j])-c[j]);
    }
    for(int o=m;o--;)
    {
        for(int i=1;i<=z;++i)dis[i]=INT_MIN;
        push(y,0,0);
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            tag[x]=0;
            for(auto &[t,i,d,k]:to[x])if(k)push(t,dis[x]+d,i);
        }
        ans+=dis[z];
        for(int i=z;i^y;)
        {
            auto &[j,k,d,w]=to[i][pre[i]];
            ++w;
            --to[j][k][3];
            i=j;
        }
        cout<<ans<<' ';
    }
    cout<<'\n';
    for(int i=1;i<=n;++i)
    {
        calc(m+i);
        cout<<a[i]<<' ';
    }
    calc(y-1);
    cout<<'\n';
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout<<fixed<<setprecision(6);
    int T=read();
    for(int i=1;i<=T;++i)
    {
        cout<<"Case #"<<i<<":\n";
        solve();
    }
}

上一题