LOJ P10018 数的划分 题解
每日一题 day52 打卡
Analysis
这道题直接搜索会TLE到**,但我们发现有很多没有用的状态可以删去,比如 1,1,5; 1,5,1; 5,1,1;
所以很容易想到一个优化:按不下降的顺序枚举划分出来的每个数。
然而还是会TLE...
再来想一个事情:n=7,k=4 已经枚举了 1,2,3 三个数,这是如果再枚举 2~7 的数就就显得非常蠢
所以你枚举的数 x 应该小于等于 n-sum(a[i])/(k-step+1),
综上,对于每个枚举的数 x ∈ {x∈N*| a[step-1]<=x<=n-sum(a[i])/(k-step+1) }
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define int long long 6 #define maxn 200+10 7 #define rep(i,s,e) for(register int i=s;i<=e;++i) 8 #define dwn(i,s,e) for(register int i=s;i>=e;--i) 9 using namespace std; 10 inline int read() 11 { 12 int x=0,f=1; 13 char c=getchar(); 14 while(c<'0'||c>'9') {if(c=='-') f=-1; c=getchar();} 15 while(c>='0'&&c<='9') {x=x*10+c-'0'; c=getchar();} 16 return f*x; 17 } 18 inline void write(int x) 19 { 20 if(x<0) {putchar('-'); x=-x;} 21 if(x>9) write(x/10); 22 putchar(x%10+'0'); 23 } 24 int n,k,ans; 25 int a[maxn]; 26 void dfs(int step) 27 { 28 if(n==0) return; 29 if(k==step) 30 { 31 if(n<a[step-1]) return; 32 ans++; 33 return; 34 } 35 rep(i,a[step-1],n/(k-step+1)) 36 { 37 a[step]=i; 38 n-=i; 39 dfs(step+1); 40 n+=i; 41 } 42 } 43 signed main() 44 { 45 n=read();k=read(); 46 a[0]=1; 47 dfs(1); 48 write(ans); 49 return 0; 50 }
请各位大佬斧正(反正我不认识斧正是什么意思)