各位肯定都读懂题了,直接上思路了。
设第二天的第i位的价格是yi ,第一天第i位的价格是xi 。我们已知y的序列,求x的。
首先
Y1由x1和x2得来 , 关系是(x1+x2)/2=y1
Y2由x1,x2和x3得来,关系是(x1+x2+x3)/3=y2;
.....此处省略一群公式
Yn由x n-1和xn得来,关系是(xn+xn-1)/2=yn;
由于Y序列都是向下取整得来的,所以x的等式都是一个范围。
y1*2<=(x1+x2)<=y1*2+1
y2*3<=(x1+x2+x3)<=y2*3+2
......
扫描二维码关注公众号,回复:
11534939 查看本文章
这里涉及到多项式之和,但是差分约束系统是二元一次不等式
所以我们需要构造Si为0到i的x序列和。
得到
y1*2<=s2-s0<=y1*2+1
y2*3<=s3-s0<=3*y2+2
.....
再加上一些条件 S1-S0>=1; S2-S1>=1; S3-S2>=1 .........略
然后构造Xi-Xj<=k 然后j到i建图跑最短路或者构造Xi-Xj>=k j到i建图跑最长路(SPFA)。初始化dis[i]=0;
#include<iostream>
#include<algorithm>
#include<string.h>
#include<cmath>
#include<vector>
#include<queue>
#include<stdio.h>
#include<string>
#define ll long long
using namespace std;
const int MAXN=305;
int C[MAXN];
struct Point
{
int v,c;
Point(int a,int b){v=a;c=b;}
};
int vis[MAXN];
int cnt[MAXN];
int dis[MAXN],n;
vector<Point>v[MAXN];
void spfa(int st) //SPFA最长路
{
queue<int> q;
for(int i=0;i<=n;i++)dis[i]=0;
q.push(st);
vis[st]=1;
memset(cnt,0,sizeof(cnt));
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(int i=0;i<v[u].size();i++){
int vv=v[u][i].v;
if(dis[vv]<dis[u]+v[u][i].c){
dis[vv]=dis[u]+v[u][i].c;
if(!vis[vv]){
vis[vv]=1;
q.push(vv);
}
}
}
}
dis[0]=0;
for(int i=1;i<=n;i++){
printf("%d%c",dis[i]-dis[i-1],(i==n)?'\n':' ');
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++){
cin>>C[i];
}
v[0].push_back(Point(2,2*C[1]));
v[2].push_back(Point(0,-(2*C[1]+1)));
v[n-2].push_back(Point(n,2*C[n]));
v[n].push_back(Point(n-2,-(2*C[n]+1)));
for(int i=2;i<=n-1;i++){
v[i-2].push_back(Point(i+1,3*C[i]));
v[i+1].push_back(Point(i-2,-(3*C[i]+2)));
}
for(int i=1;i<=n;i++){
v[i-1].push_back(Point(i,1));
}
spfa(0);
}