一、题目
二、解法
暴力的做法就不说了,我们可以从前往后,从后往前来跑背包,设为 f 1 [ i ] [ j ] , f 2 [ i ] [ j ] f_1[i][j],f_2[i][j] f1[i][j],f2[i][j],询问时我们排除给定的物品,找到 l , r l,r l,r,然后合并 f 1 [ l ] f_1[l] f1[l]和 f 2 [ r ] f_2[r] f2[r],合并一次是 O ( e ) O(e) O(e)的。
具体实现有一个小技巧,把多重背包拆成若干个物品跑 0 / 1 0/1 0/1背包(二进制拆法),可参考我的代码。
#include <cstdio>
#include <iostream>
using namespace std;
#define int long long
int read()
{
int x=0,flag=1;char c;
while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;
while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x*flag;
}
int T,p1,p2,k;
int gcd(int a,int b)
{
return !b?a:gcd(b,a%b);
}
signed main()
{
T=read();
while(T--)
{
p1=read();p2=read();k=read();
if(p1>p2) swap(p1,p2);
if(k==1)
{
puts("No");
continue;
}
if(p2%p1==0)
{
int t=p2/p1-1;
if(t<k) puts("Yes");
else puts("No");
continue;
}
int t=p1/gcd(p1,p2)-1;
int x=p2/p1+((p2%p1)*t>=p1);
if(x<k) puts("Yes");
else puts("No");
}
}