之前做过差分,但是没做过差分约束系统。
正好在学军机房听课讲到这道题,就顺带学了一下。
其实…就是列不等式组然后建图
作为蒟蒻,当然是不会加二分优化的啦…但是poj上还是94ms跑过了qwq
(其实是懒qwq)
解题分析放代码里了。
/*
算法:差分约束系统+二分
思路:设读入的人中,从i时刻开始的人数为num[i],雇佣的人数为x[i]。
i时刻需要的人为r[i]
据此,可以列出两个不等式:
1. 0<=x[i]<=num[i]
2.sum( x[j] )>=r[i] (j=i-7~i)
很容易想到用前缀和。
s[i]=sum( x[j] ),j=1~i
1. s[i]-s[i-1]<=num[i]
2. s[i]-s[i-8]>=r[i] 8<=i<=24
s[i]-s[i+16]+s[24]>=r[i] 1<=i<8
(s[i]-s[i+16]>=r[i]-s[24])
二分s[24],然后建图,根据差分约束系统.
ps:差分约束系统中如果是>=,要么跑最长路,要么不等式两边同时*(-1)
*/
#include <iostream>
#include <queue>
using namespace std;
#define MAXN 25
#define inf 1<<20
struct node
{
int to,weight,next;
}a[MAXN*30];
int head[MAXN],dis[MAXN],cnt[MAXN];
int tot,n,r[MAXN],t[MAXN];
bool vis[MAXN];
void add( int u,int v,int w ) //邻接表
{
a[tot].to=v; a[tot].weight=w; a[tot].next=head[u]; head[u]=tot++;
}
void mem() //初始化
{
tot=0;
for ( int i=0; i<MAXN; i++ )
{
head[i]=-1; dis[i]=inf; vis[i]=0; cnt[i]=0;
}
dis[0]=0;
}
void build( int ans ) //根据差分关系建图
{
mem();
add( 0,24,-ans );
for ( int i=1; i<MAXN; i++ )
{
add( i-1,i,0 ); add( i,i-1,t[i] );
}
for ( int j=1; j<MAXN; j++ )
{
int i=(j+8)%24;
if ( i>j ) add( j,i,-r[i] );
else add( j,i,-r[i]+ans );
}
}
/*
SPFA判断是否有解
因为这个解只有两种情况,无解和有解,而只要不是无解,
第一个找到的有解即为最优解,所以只要没有负环就可以return 1
其实这里可以加二分优化(单调性,人总是越多越好),但是程序中采用了直接枚举,
复杂度也是可以接受的。
*/
bool check( int ans )
{
queue<int> q;
q.push( 0 ); vis[0]=1; cnt[0]=1;
while ( !q.empty() )
{
int p,t=q.front();
q.pop(); p=head[t]; vis[t]=0;
while ( p!=-1 )
{
if ( dis[a[p].to] > dis[t]+a[p].weight )
{
dis[a[p].to]=dis[t]+a[p].weight;
if ( !vis[a[p].to] )
{
vis[a[p].to]=1;
q.push( a[p].to );
cnt[a[p].to]++;
if ( cnt[a[p].to]>24 ) return 0;
}
}
p=a[p].next;
}
}
return 1;
}
int main()
{
int T;
scanf( "%d",&T );
while ( T-- )
{
for ( int i=1; i<=24; i++ )
{
scanf( "%d",&r[i] ); t[i]=0;
}
scanf( "%d",&n );
for ( int i=0; i<n; i++ )
{
int tmp;
scanf( "%d",&tmp ); t[tmp+1]++;
}
bool flag=1;
for ( int i=0; i<=n; i++ )
{
build( i );
if ( check(i) )
{
printf( "%d\n",i );
flag=0; break;
}
}
if ( flag ) printf( "No Solution\n" );
}
}
update 2020.3.26
发现这道题lyd书里也有…… 393.雇佣收银员
tql
ORZ
%%%%%%%%%%%%%%%%%%
您也很巨QAQ
我没有啊
tql
orz
STO