题目大意
有
n
个商店,第
现在有
m
个询问,第
Data Constraint
ti,Ti≤n≤300,vi≤300,ci,Mi≤109
题解
很容易可以想到先按时间排序,再用两个指针扫,这样就可以排除时间的影响。
设
fi
表示当前这些物品中,要得到价值
i
至少需要的空间是多少。这个转移很简单。
再设
现在考虑二分答案,如果当前的
gmid≤Mi
那么这个
mid
显然就是合法的。
时间复杂度: O(n3log(MaxAns))
SRC
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std ;
#define N 300 + 10
#define K 90000 + 10
#define M 100000 + 10
typedef long long ll ;
struct Shops {
int c , v , t ;
} S[N] ;
struct Plans {
int T , lim , h ;
} P[M] ;
ll f[K] , g[K] ;
int sum[N] , ans[M] ;
int n , m ;
bool cmp1( Shops a , Shops b ) { return a.t < b.t ; }
bool cmp2( Plans a , Plans b ) { return a.T < b.T ; }
int main() {
freopen( "market.in" , "r" , stdin ) ;
freopen( "market.out" , "w" , stdout ) ;
scanf( "%d%d" , &n , &m ) ;
for (int i = 1 ; i <= n ; i ++ ) scanf( "%d%d%d" , &S[i].c , &S[i].v , &S[i].t ) ;
for (int i = 1 ; i <= m ; i ++ ) scanf( "%d%d" , &P[i].T , &P[i].lim ) , P[i].h = i ;
sort( S + 1 , S + n + 1 , cmp1 ) ;
sort( P + 1 , P + m + 1 , cmp2 ) ;
for (int i = 1 ; i <= n ; i ++ ) sum[i] = sum[i-1] + S[i].v ;
memset( f , 63 , sizeof(f) ) ;
memset( g , 63 , sizeof(g) ) ;
f[0] = g[0] = 0 ;
int h = 0 ;
for (int i = 1 ; i <= m ; i ++ ) {
while ( h < n && S[h+1].t <= P[i].T ) {
h ++ ;
for (int j = sum[h] ; j >= 0 ; j -- ) {
if ( j >= S[h].v ) f[j] = min( f[j] , f[j-S[h].v] + S[h].c ) ;
g[j] = min( g[j+1] , f[j] ) ;
}
}
int l = 0 , r = sum[h] ;
while ( l <= r ) {
int mid = (l + r) / 2 ;
if ( g[mid] <= P[i].lim ) l = mid + 1 , ans[P[i].h] = mid ;
else r = mid - 1 ;
}
}
for (int i = 1 ; i <= m ; i ++ ) printf( "%d\n" , ans[i] ) ;
return 0 ;
}
以上.