Counting Sequences I
拿着OEIS上的一個類似的序列(當時以爲是相同的)懟了半天。。。欲哭無淚
題意:問有多少長度爲的正整數序列滿足它們的和等於它們的積(每一位置對應相同認爲是同一序列)
思路:沒啥思路,暴力即可
- 首先,序列中不等於的值不能太多,比如等於4096,顯然乘積增長太快了!因此大多數序列都會被剪枝掉,保證了時間複雜度很低
- 枚舉的過程按從大到小的方式進行枚舉,在每個位置都檢驗一遍是否後面所有數字都取是剛好合理的
- 若合理,則直接使用 計算出這些數字能產生的合法序列數
題面描述
恰好卡過去的暴力代碼
#include "bits/stdc++.h"
#define hhh printf("hhh\n")
#define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
using namespace std;
typedef long long ll;
typedef pair<int,int> pr;
inline int read() {int x=0;char c=getchar();while(c<'0'||c>'9')c=getchar();while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();return x;}
const int maxn = 1e5+10;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
const double eps = 1e-7;
int a[30];
ll f[maxn], inv[maxn];
ll dfs(int n, int cur, int pre, int l, int r) {
if(l+n+1-cur==r) {
ll ans=f[n], now=1;
for(int i=2; i<cur; ++i)
if(a[i]==a[i-1]) now++;
else ans=ans*inv[now]%mod, now=1;
if(cur>1&&a[cur-1]!=1) ans=ans*inv[now]%mod*inv[n+1-cur]%mod;
else ans=ans*inv[now+n+1-cur]%mod;
return ans;
}
if(cur>n||pre==1) return 0;
ll ans=0;
for(int i=min(n,pre); i>=1; --i)
if(l+i+n-cur>=r*i) a[cur]=i, ans=(ans+dfs(n,cur+1,i,l+i,r*i))%mod;
return ans;
}
int main() {
//ios::sync_with_stdio(false); cin.tie(0);
f[0]=1; for(int i=1; i<=3000; ++i) f[i]=i*f[i-1]%mod;
inv[0]=inv[1]=1;
for(int i=2; i<=3000; ++i) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
for(int i=2; i<=3000; ++i) inv[i]=inv[i]*inv[i-1]%mod;
int T=read();
while(T--) printf("%lld\n", dfs(read(),1,inf,0,1));
}