给你n个价格范围l,r,问最后没组价格的上下浮动能不能不超过k
如果 i 是在 [l, r] 范围内, 那么 i + 1 必须要在 [l-k, r + k] 范围内.这是因为如果 i + 1 选了范围外的值, i 就无解了.
这样可以从左往右, 把左边的约束带到右边.再从右往左做一遍.最后剩下的区间应该就是可行域.因为题目只要求一种方案, 全部选最低的即可.复杂度 O(n).
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
#define PI acos(-1)
const int maxn = 1e5+5;
const ll mod = 1e9;
const double eps = 1e-6L;
ll n,k;
struct node
{
ll l,r;
} a[maxn];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%lld %lld",&n,&k);
for(int i=0; i<n; i++)
{
scanf("%lld %lld",&a[i].l,&a[i].r);
}
ll left=a[0].l,right = a[0].r;
bool flag = true;
for(int i=1; i<n; i++)
{
left = left-k;
right = right+k;
a[i].l = max(a[i].l,left);
a[i].r = min(a[i].r,right);
left = a[i].l;
right = a[i].r;
if(a[i].l>a[i].r)
flag = false;
}
left=a[n-1].l,right = a[n-1].r;
for(int i=n-2; i>=0; i--)
{
left = left-k;
right = right+k;
a[i].l = max(a[i].l,left);
a[i].r = min(a[i].r,right);
left = a[i].l;
right = a[i].r;
if(a[i].l>a[i].r)
flag = false;
}
if(!flag) puts("NO");
else
{
puts("YES");
for(int i=0; i<n; i++)
{
if(i)printf(" ");
printf("%d",a[i].l);
}
puts("");
}
}
return 0;
}
/*
*/