昨天晚上学长讲了这题,说是什么线段树分治,然后觉得不可做,但那还不是正解,然后感觉好像好难的样子。
由于什么鬼畜的分治不会好打,然后想了一下$O(nm)$的做法,想了好长时间觉得这题好像很像大力容斥。然后疯狂yy
正经题解:
$O(n^2m)$的解法很好想,就是一个个枚举,但是显然时间吃不消,在观察题目,根据zzh学长的根据题目核心性质猜测法(雾
我们可以考虑容斥因为他题目的限制条件就是每次去掉一个物体,那么就可以先$O(nm)$处理出没有限制条件的总方案数,然后单步容斥,枚举每次去掉的物品,然后把那种物品的方案数剪掉即可
时间复杂度$O(nm)$
最后记得多取模。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 #include<vector> 8 using namespace std; 9 const int N=4e3+10; 10 int v[N],f[N],g[N]; 11 int n,m; 12 int main(){ 13 scanf("%d%d",&n,&m); 14 for(int i=1;i<=n;i++) scanf("%d",&v[i]); 15 f[0]=1; 16 for(int i=1;i<=n;i++) for(int j=m;j>=v[i];j--) (f[j]+=f[j-v[i]])%=10; 17 for(int i=1;i<=n;i++){ 18 for(int j=0;j<=m;j++) g[j]=f[j]%10; 19 for(int j=v[i];j<=m;j++){ 20 g[j]=((g[j]-g[j-v[i]])%10+10)%10; 21 } 22 for(int i=1;i<=m;i++) printf("%d",g[i]); 23 puts(""); 24 } 25 }