LUOGU P4163 [SCOI2007]排列】的更多相关文章

传送门 解题思路 首先我们发现这道题s的长度很小,所以考虑点暴力的做法,状压dp或搜索.本蒟蒻搜索永远调不对,所以就写了个状压dp.因为所有s里的数都要出现一次,并且最后的答案是要求整除,那么我们设dp[S][k]表示现在所选的状态集合为S,当前所选的数组成的数字对d取余后的值为k,这样就可以转移了.首先枚举所有的状态S,然后再枚举所有没有被选的数j,再枚举余数k即可转移. 转移方程为:dp[S|(1<<(j-1))][(k*10+a[j])%d]+=dp[S][k];但是这样写是错误的,因为…
P4163 [SCOI2007]排列 注意要排序: next_permutation prev_permutation #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ; typedef long long ll; int T,n,d; int a[maxn]; char s[maxn]; ll ans; int main() { scanf("%d&quo…
状压dp (看到s的长度不超过10就很容易想到是状压dp了 但是这个题的状态转移方程比较特殊) 题目大意 给一个数字串 s 和正整数 d, 统计 s 有多少种不同的排列能被 d 整除(可以有前导 0).例如 123434有 90 种排列能被 2 整除,其中末位为 2 的有 30 种,末位为 4 的有 60种. 输入格式 输入第一行是一个整数 T,表示测试数据的个数,以下每行一组 s 和 d,中间用空格隔开.s 保证只包含数字 0,1,2,3,4,5,6,7,8,9 输出格式 每个数据仅一行,表示…
1072: [SCOI2007]排列perm Description 给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0).例如123434有90种排列能被2整除,其中末位为2的有30种,末位为4的有60种. Input 输入第一行是一个整数T,表示测试数据的个数,以下每行一组s和d,中间用空格隔开.s保证只包含数字0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Output 每个数据仅一行,表示能被d整除的排列的个数. Sample Input 7 000…
1072: [SCOI2007]排列perm Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 805  Solved: 497[Submit][Status] Description 给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0).例如123434有90种排列能被2整除,其中末位为2的有30种,末位为4的有60种. Input 输入第一行是一个整数T,表示测试数据的个数,以下每行一组s和d,中间用空格隔开.s保证只包…
1072: [SCOI2007]排列perm Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1268  Solved: 782[Submit][Status][Discuss] Description 给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0).例如123434有90种排列能被2整除,其中末位为2的有30种,末位为4的有60种. Input 输入第一行是一个整数T,表示测试数据的个数,以下每行一组s和d,中间用…
1072: [SCOI2007]排列perm Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2488  Solved: 1546[Submit][Status][Discuss] Description 给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0).例如123434有90种排列能被2整除,其中末位为2的有30种,末位为4的有60种. Input 输入第一行是一个整数T,表示测试数据的个数,以下每行一组s和d,中间…
Description 给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0).例如123434有90种排列能被2整除,其中末位为2的有30种,末位为4的有60种. Input 输入第一行是一个整数T,表示测试数据的个数,以下每行一组s和d,中间用空格隔开.s保证只包含数字0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Output 每个数据仅一行,表示能被d整除的排列的个数. Sample Input 7 000 1 001 1 1234567890 1 1…
Description 给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0).例如123434有90种排列能被2整除,其中末位为2的有30种,末位为4的有60种.Input 输入第一行是一个整数T,表示测试数据的个数,以下每行一组s和d,中间用空格隔开.s保证只包含数字0, 1, 2, 3, 4, 5, 6, 7, 8, 9.Output 每个数据仅一行,表示能被d整除的排列的个数.Sample Input7000 1001 11234567890 1123434 21…
题目链接:BZOJ 1072 这道题使用 C++ STL 的 next_permutation() 函数直接暴力就可以AC .(使用 Set 判断是否重复) 代码如下: #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <cmath> #include <set>…
题意:给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0) 100%的数据满足:s的长度不超过10, 1<=d<=1000, 1<=T<=15 看到整除应该往余数方面想 $f[s][i]$表示当前已经选择的数的集合为$s$,余数为$i$的方案数 枚举下一个数字,用更新的写法转移 注意是有重复元素的排列!除上个阶乘 #include <iostream> #include <cstdio> #include <cstring&g…
http://www.lydsy.com/JudgeOnline/problem.php?id=1072 首先无限膜拜题解orz表示只会暴力orz 数据那么小我竟然想不到状压! orz 这种题可以取模设状态orz f[i,j]表示状态为i,mod d为j的方案 则答案为f[all, 0] 转移就太简单了orz f[i|1<<k, (j*10+c[k])%d]+=f[i, j] 然后按照多重集合的做法最后答案/(xi!) 然后我有一sb错一直没找到,wa了n发... QAQ #include &…
又颓废了一个下午,最近撸mc撸到丧失意识了,玩的有点恶心,于是找水题做,瞧不起颓废的自己啊. another水题. 这题题意很明显啦,就是找数字排列后组成的数去mod d=0后有多少种. 普通的搜索的话,是会tle的(应该是o(n!)没错?).注意到长度n还是比较小的,于是想到状压dp. 状态就是每个数取和不取组成的结果(就是00110表示第3,4个数取了啦,学过状压都知道). 然后转移就是f[i,j,k]表示现在取到第i个数状态为i余数为j有多少种情况, 那么f[i,j,(k*10+a[i])…
暴力,next_permutation函数用于枚举出下一个排列.sscanf函数用于将字符串转化成数字. #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,len,ans; long long x,t; ]; int main() { scanf("%d",&n); ;i<=n;i++) { ans=; scanf(&quo…
和Luogu 4302 [SCOI2003]字符串折叠 差不多的想法,区间dp 为了计算方便,我们可以假设区间[l, r]的前面放了一个M,设$f_{i, j, 0/1}$表示区间$[i, j]$中是否存在M 因为这题只能是二的幂次倍压缩,所以转移的时候枚举中点chk是否合法,如果合法那么 $f_{i, j, 0} = f_{i, (i + j) / 2 - 1, 0} + 1$ 除了区间压缩,还可以通过加法构成最优答案 1.当中间加入了M,枚举M加入的位置 $f_{i, j, 1} = min…
Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3000  Solved: 1875[Submit][Status][Discuss] Description 给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0).例如123434有90种排列能被2整除,其中末位为2的有30种,末位为4的有60种. Input 输入第一行是一个整数T,表示测试数据的个数,以下每行一组s和d,中间用空格隔开.s保证只包含数字0, 1, 2,…
Description 给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0).例如123434有90种排列能被2整除,其中末位为2的有30种,末位为4的有60种. Input 输入第一行是一个整数T,表示测试数据的个数,以下每行一组s和d,中间用空格隔开.s保证只包含数字0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Output 每个数据仅一行,表示能被d整除的排列的个数. Sample Input Sample Output HINT 在前三个例子中,排…
很简单的状压dp,但是有一个事,就是...我数组开大了一点,然后每次memset就会T,然后开小就好了!!!震惊!以后小心点这个问题. 题干: Description 给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0).例如123434有90种排列能 被2整除,其中末位为2的有30种,末位为4的有60种. Input 输入第一行是一个整数T,表示测试数据的个数,以下每行一组s和d,中间用空格隔开.s保证只包含数字0, , , , , , , , , . Output…
Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1862  Solved: 1171 [Submit][Status][Discuss] Description 给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0).例如123434有90种排列能 被2整除,其中末位为2的有30种,末位为4的有60种. Input 输入第一行是一个整数T,表示测试数据的个数,以下每行一组s和d,中间用空格隔开.s保证只包含数字0, 1 ,…
有一种暴力算法就是直接枚举. 正解就是状压dp 令f[i][j]:i:使用的数位的状态j:当前的模数 边界:f[0][0] = 1; f[i|1<<k][j*10+k % n] += f[i][j] | !(i&(1<<k)) 答案就是f[i<<len-1][0] 进行了一些重复处理. #include <bits/stdc++.h> using namespace std; const int maxn = 15; int main() { //…
传送门 dalao们怎么状态都设的两维以上啊?qwq 完全可以一维状态的说 设\(f[i]\)为前缀i的答案,转移就枚举从前面哪里转移过来\(f[i]=min(f[j-1]+w(j,i))(j\in [1,i])\) 现在要知道\(w(i,j)\)怎么写,也就是区间\([i,j]\)的最小长度(要求区间最多只能在开头有一个W),首先不压缩的长度就是原长度,然后压缩的话先要在开头加W,然后每次压缩一个最长的可以拆成两个相同串的前缀,压缩完后长度会加上1(后面接R),减去那个前缀的一半长度,然后那个…
原题传送门 题目要求无法逃离的最少有多少 直接做肯定不好做,我们帮题目变一个说法:最多能逃离多少 这个询问一看就是最大流 考虑如何建图: 1.将S和每一个有蜥蜴的点连一条流量为1的边(每个蜥蜴只能用1次) 2.每个点拆成两个点(一个点用来连接从其他点连来的边,另一个点用来向其他的点连边,下同),从前一个点向后一个点连一条流量为石柱高度的边(每个石柱只能踩它的高度次) 3.能互相到达的石柱之间连一条流量为inf的边 4.将每一个能跳出地图的点向T连一条流量为inf边 建图后跑一下最大流即可求出答案…
看了看数据范围...我艹...爆搜可过? 等等,冷静,让我看一眼题解...我艹...真可过... emm...再冷静分析...emm...还是写状压吧... 这题主要的思路就是 f[i][j] 表示 在 i 号状态下 总和%d为 j 的情况 这样我们只用判断这个方案合不合法即可... 对了,因为有重复数字,所以要去重... 呆码: #include<iostream> #include<cstdio> #include<cstring> using namespace…
晚上XZTdalao给我推荐了这道数论题.太棒了又可以A一道省选题了 其实这道题也就考一个错排公式+组合数+乘法逆元 我们来一步一步分析 错排公式 通俗的说就是把n个1~n的数排成一个序列A,并使得所有的a[i]!=i(1<=i<=n) 对于这道题我们可以进行转化,要求m个a[i]==i的个数,我们可以把它转化成求(n-m)个a[i]!=i的个数 然后用到错排公式: d[i]=(i-1)*(d[i-1]+d[i-2]) 其中d[i]表示i个数的错排方案 组合数 这个就比较简单了,比较经典的公式…
状压dp,f[i][j]表示当前取了i,模数余j的状态. 然后向后推,枚举可能的数即可. 注意每个数存在重复,最后要除以相应出现次数的阶乘. #include<bits/stdc++.h> using namespace std; ],c[],len,f[][],ans; ]; int main(){ int T;scanf("%d",&T); while(T--){ memset(c,,,sizeof(f)); scanf(][]=; ;i<len;i++)…
[题目分析] 没什么好说的,水题. 代码比较丑,结果需要开long long 时间爆炸 [代码] #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define F(i,j,k) for (ll i=j;i<=k;++i) #define ll long long ll T,n,d,dp[1<<…
先写了个next_permutation结果T了,于是开始写状压 设f[s][i]为选取状态为s,选的数模d为i的方案数,去重的话直接除以每个数字的出现次数的阶乘即可 #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=20; int T,d,n,a[N],fac[N],c[N],f[2005][2005]; char s[N]; int main(…
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1072 分析:看了题解才知道,状态的设计很巧妙,用余数表示,即f[i][j]表示二进制状态i下余数为j的方案数,然后列一列式子就可以了,注意排除相同数字的情况. #include<cstring> #include<algorithm> #include<cstdio> #include<string> using namespace std; ;…
code: #include <bits/stdc++.h> #define N 1005 using namespace std; void setIO(string s) { string in=s+".in"; string out=s+".out"; freopen(in.c_str(),"r",stdin); // freopen(out.c_str(),"W",stdout); } char str[N…
LINK:最大土地面积 容易想到四边形的边在凸包上面 考虑暴力枚举凸包上的四个点计算面积. 不过可以想到可以直接枚举对角线的两个点找到再在两边各找一个点 这样复杂度为\(n^3\) 可以得到50分. 考虑继续优化 观察 那个点可以三分做 所以复杂度为\(n^2log\) 最后可以模拟旋转卡壳的过程 枚举两个点i和j的时候 随着j的增大那么之前的点单调递增 所以可以单调的增加 这样就不需要枚举第三个点了. 复杂度\(n^2\) //#include<bits\stdc++.h> #include…