CSP-S模拟测试 88 题解
T1 queue:
考场写出dp柿子后觉得很斜率优化,然后因为理解错了题觉得斜率优化完全不可做,只打了暴力。
实际上他是可以乱序的,所以直接sort,正确性比较显然,贪心可证,然后就是个sb斜率优化dp了
T2:
究极大模拟,懒得打,鸽了
T3:
蒟蒻博主用的是记忆化搜索的方法,其实和抵制克苏恩那题思路很像,因为他的小球个数很少,颜色种数也很少,所以这是可行的,记搜时我们只需记录还有多少个1个的,2个的,3个的,和上一个选取的是剩几个的,然后这一次可能选剩1个的,2个的,3个的,如果这次选的和上次选的有可能一样就减掉一种可能,然后直接记搜就好了,数据范围需要高精,然而我没脸用int128水过。
1 #include<bits/stdc++.h> 2 using namespace std; 3 signed k[20],cnt[20]; 4 #define int __int128 5 int f[20][20][20][20]; 6 int dfs(int i,int j,int k,int x){ 7 if(!i&&!j&&!k) return 1; 8 if(f[i][j][k][x]) return f[i][j][k][x]; 9 int res=0; 10 if(i) res+=(i-(x==1))*dfs(i-1,j,k,0); 11 if(j) res+=(j-(x==2))*dfs(i+1,j-1,k,1); 12 if(k) res+=(k-(x==3))*dfs(i,j+1,k-1,2); 13 return f[i][j][k][x]=res; 14 } 15 void print(int x){ 16 if(!x)return ; 17 print(x/10); 18 putchar(x%10+'0'); 19 } 20 signed main(){ 21 signed n,sum=0; 22 scanf("%d",&n); 23 for(int i=1;i<=n;++i) scanf("%d",&k[i]),cnt[k[i]]++,sum+=k[i]; 24 print(dfs(cnt[1],cnt[2],cnt[3],0)); 25 }