Questions surface: https://www.cnblogs.com/Juve/articles/11615883.html
Country X Army:
It seems to have O (T * N) Direct greedy practices
In fact, with more than half of a log can be over
First of all positions by ba descending order (after this program, the sort order is optimal sweep)
Then half of the answer
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define int long long #define re register using namespace std; const int MAXN=1e5+5; inline int read(){ re int x=0;re char ch=getchar(); while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0',ch=getchar();} return x; } int t,n,l,r; struct node{ int a,b; inline friend bool operator < (node p,node q){ return p.b-p.a>q.b-q.a; } }c[MAXN]; inline bool check(re int x){ for(re int i=1;i<=n;++i){ if(x<c[i].b) return 0; x-=c[i].a; } return 1; } signed main(){ t=read(); while(t--){ n=read(); l=0,r=0; for(re int i=1;i<=n;++i){ c[i].a=read(),c[i].b=read(); l+=c[i].a,r+=c[i].b; } sort(c+1,c+n+1); while(l<r){ re int mid=(l+r)>>1; if(check(mid)) r=mid; else l=mid+1; } printf("%lld\n",l); } return 0; }
Permutations:
The $ C_ {n} ^ {i} * C_ {n} ^ {i} $ into $ C_ {n} ^ {i} * C_ {n} ^ {ni} $,
In this case, that is, for each i, among n number of programs selected by the i-th of the n selected (ni) of the program number, the last add up.
Such answers obtained, in fact, equivalent to 2n of the article, a first n-i selected, selected after n (ni) th ,,
Also, because i runs over all integers from 0 to n, then the number of the accumulated programs is equal to $ C_ {2 * n} ^ {n} $.
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define int long long #define re register using namespace std; const int MAXN=2e6+5; const int mod=1e9+7; int t,n,fac[MAXN],inv[MAXN]; inline int q_pow(re int a,re int b,re int p){ re int res=1; while(b){ if(b&1) res=res*a%p; a=a*a%p; b>>=1; } return res; } inline void get_c(re int N){ fac[0]=fac[1]=inv[0]=1; for(re int i=2;i<=N;++i){ fac[i]=fac[i-1]*i%mod; } inv[N]=q_pow(fac[N],mod-2,mod); for(re int i=N-1;i>=1;--i){ inv[i]=inv[i+1]*(i+1)%mod; } } inline int C(re int n,re int m){ if(m>n) return 0; if(m==n) return 1; return fac[n]%mod*inv[m]%mod*inv[n-m]%mod; } signed main(){ get_c(2e6); scanf("%lld",&t); while(t--){ scanf("%lld",&n); printf("%lld\n",C(2*n,n)); } return 0; }
Palindrome:
Definition of G [i] [j] indicates whether the i to j palindrome this section, may be formed g [i + 1] [j-1] Transfer:
for(int i=1;i<=len;++i){ g[i][i]=1; f[i][i]=1; for(int j=1;j<=min(i-1,len-i);++j){ if(s[i-j]==s[i+j]){ g[i-j][i+j]=1; }else break; } } for(int i=1;i<=len-1;++i){ if(s[i]==s[i+1]){ g[i][i+1]=1; f[i][i+1]=3; for(int j=1;j<=min(i-1,len-i-1);++j){ if(s[i-j]==s[i+1+j]){ g[i-j][i+1+j]=1; }else break; } } }
Definition of F [i] [j] denotes the i to j answers this
有转移:$f[l][r]=f[l+1][r]+f[l][r-1]-f[l+1][r-1]+g[l][r]$
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define int long long #define re register using namespace std; const int MAXN=5005; char s[MAXN]; int t,len,f[MAXN][MAXN]; bool g[MAXN][MAXN]; signed main(){ scanf("%s",s+1); len=strlen(s+1); for(int i=1;i<=len;++i){ g[i][i]=1; f[i][i]=1; for(int j=1;j<=min(i-1,len-i);++j){ if(s[i-j]==s[i+j]){ g[i-j][i+j]=1; }else break; } } for(int i=1;i<=len-1;++i){ if(s[i]==s[i+1]){ g[i][i+1]=1; f[i][i+1]=3; for(int j=1;j<=min(i-1,len-i-1);++j){ if(s[i-j]==s[i+1+j]){ g[i-j][i+1+j]=1; }else break; } } } for(int i=2;i<=len;++i){ for(int l=1;l<=len-i+1;++l){ int r=l+i-1; f[l][r]=f[l+1][r]+f[l][r-1]-f[l+1][r-1]+g[l][r]; } } scanf("%lld",&t); while(t--){ re int l,r; scanf("%lld%lld",&l,&r); printf("%lld\n",f[l][r]); } return 0; }