传送门:CCF201809-4 再卖菜
差分约束,可以参考这里。
#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 3e2+3;
struct Edge
{
int v, w;
Edge() {}
Edge(int v, int w): v(v), w(w) {}
};
int n, a[maxn];
int dis[maxn], vis[maxn];
vector<Edge> g[maxn];
void read()
{
cin >> n;
for(int i = 1; i <= n; ++i)
cin >> a[i];
}
void spfa()
{
queue <int> q;
for(int i = 0; i <= n; ++i)
{
q.push(i);
vis[i] = 1;
dis[i] = 0;
}
while(!q.empty())
{
int u = q.front();
q.pop();
vis[u] = 0;
for(int i = 0; i < g[u].size(); ++i)
{
int v = g[u][i].v, w = g[u][i].w;;
if(dis[v] < dis[u]+w)
{
dis[v] = dis[u]+w;
if(!vis[v])
{
q.push(v);
vis[v] = 1;
}
}
}
}
}
void solve()
{
g[0].push_back(Edge(2, 2*a[1]));
g[2].push_back(Edge(0, -2*a[1]-1));
for(int i = 0; i <= n-3; ++i)
{
g[i].push_back(Edge(i+3, 3*a[i+2]));
g[i+3].push_back(Edge(i, -3*a[i+2]-2));
}
if(n > 2)
{
g[n-2].push_back(Edge(n, 2*a[n]));
g[n].push_back(Edge(n-2, -2*a[n]-1));
}
for(int i = 0; i < n; ++i)
g[i].push_back(Edge(i+1, 1));
spfa();
for(int i = 1; i <= n; ++i)
cout << dis[i]-dis[i-1] << ' ';
}
int main()
{
read();
solve();
return 0;
}