#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1e4+5;
int main(){
int T;
scanf("%d",&T);
while(T--){
int n,d;
scanf("%d%d",&n,&d);
if(d<=n) puts("YES");
else {
int x=sqrt(d);
int ans=min(ceil(1.0*d/x)+x,ceil(1.0*d/(x+1))+(x+1));
if(ans<=n+1) puts("YES");
else puts("NO");
}
}
}
对式子进行化简即可发现规律 ,偷懒直接贴官方的题解
#include<cstdio>
#include<iostream>
#include<algorithm>
typedef long long ll;
using namespace std;
int main(){
int T;
cin>>T;
while(T--){
int a,b;
cin>>a>>b;
ll now=9,cnt=0;
while(now<=b){
now=now*10+9;
cnt++;
}
cout<<1ll*a*cnt<<endl;
}
}
两种方法,都需要发现一个性质就是一个长度为2*m的非递减序列仅能构造出一个解
所以这道题本质上是找到使用1-n能凑出多少个不同的非递减序列,并且不能重复
法一:
法二:问题等价于1-n中每一个数有无限个,从中挑出2*m个元素组成一个集合,有多少种选法,答案是
#include<cstdio>
#include<iostream>
#include<algorithm>
typedef long long ll;
using namespace std;
const ll P=1e9+7;
ll jc[1100],inv[1100];
ll qpow(ll a,int n){
ll ans=1;
for(;n;n>>=1,a=a*a%P)
if(n&1) ans=ans*a%P;
return ans;
}
int main(){
jc[0]=1;
for(int i=1;i<=1050;i++){
jc[i]=jc[i-1]*i%P;
inv[i]=qpow(jc[i],P-2);
}
inv[0]=1;
int n,m;
cin>>n>>m;
cout<<jc[n+2*m-1]*inv[2*m]%P*inv[n-1]%P<<endl;
}