ACM_错排(递推dp)】的更多相关文章

支离破碎 Time Limit: 4000/2000ms (Java/Others) Problem Description: 远古时期有一位魔王想向一座宫殿里的公主求婚.为了考验魔王的智力,太后给了他这样一道题:给出一串珠子(大小相同)共 n 个,现在要求魔王将所有的珠子分成不超过(<=)m 堆并求出所有可能的总情况数.考虑到m,n较大时,整座宫殿都可能放不下,现在只需要他求出总情况数 mod M 的答案,聪明的你能帮魔王解决这个问题吗? Input: 第一行输入两个整数 n 和 m.第二行输…
不容易系列之一 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 16646 Accepted Submission(s): 6935 Problem Description 大家常常感慨,要做好一件事情真的不容易,确实,失败比成功容易多了!做好“一件”事情尚且不易,若想永远成功而总从不失败,那更是难上加难了,就像花钱总是比挣钱容易的道理一样.话…
当n个编号元素放在n个编号位置,元素编号与位置编号各不对应的方法数用M(n)表示,那么M(n-1)就表示n-1个编号元素放在n-1个编号位置,各不对应的方法数,其它类推. 第一步,把第n个元素放在一个位置,比如位置k,一共有n-1种方法: 第二步,放编号为k的元素,这时有两种情况 ⑴把它放到位置n,那么,对于剩下的n-1个元素,由于第k个元素放到了位置n,剩下n-2个元素就有M(n-2)种方法: ⑵第k个元素,不把它放到位置n,这时,对于这n-1个元素,有M(n-1)种方法: 综上得到: M(n…
题目传送门 题意:k个马棚,n条马,黑马1, 白马0,每个马棚unhappy指数:黑马数*白马数,问最小的unhappy值是多少分析:dp[i][j] 表示第i个马棚放j只马的最小unhappy值,状态转移方程:dp[i][j] = min (dp[i][j], dp[i-1][k-1] + cur * (j - k + 1 - cur)); 表示k到j匹马放在第i个马棚的最小unhappy值,dp[0][0] = 0.由于黑马数是1的和,前缀sum[i]表示前i匹马黑马的个数,白马就是总个数-…
题目传送门 /* 题意:给n块砖头,问能组成多少个楼梯,楼梯至少两层,且每层至少一块砖头,层与层之间数目不能相等! 递推DP:dp[i][j] 表示总共i块砖头,最后一列的砖头数是j块的方案数 状态转移方程:dp[i][j] += dp[i-j][k] 表示最后一列是j,那么上一个状态是少了最后一列 总共i-j块砖头,倒数第二列是k块砖头.k<j, j<=i 最后累加dp[n][i], i<n因为最少要两层 dp[0][0] = 1; 还有更简单的做法,没看懂:http://m.blog…
题目传送门 /* 递推DP: dp[i] 表示放i的方案数,最后累加前n-2的数字的方案数 */ #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> using namespace std; ; const int INF = 0x3f3f3f3f; ]; int main(void) //URAL 1260 Nudnik Photographer { //fr…
题目传送门 /* 题意:1~1e9的数字里,各个位数数字相加和为s的个数 递推DP:dp[i][j] 表示i位数字,当前数字和为j的个数 状态转移方程:dp[i][j] += dp[i-1][j-k],为了不出现负数 改为:dp[i][j+k] += dp[i-1][j] */ #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <str…
题目传送门 /* 题意:已知起点(1,1),终点(n,m):从一个点水平或垂直走到相邻的点距离+1,还有k个抄近道的对角线+sqrt (2.0): 递推DP:仿照JayYe,处理的很巧妙,学习:) 好像还要滚动数组,不会,以后再补 */ #include <cstdio> #include <iostream> #include <algorithm> #include <cmath> #include <cstring> using names…
题目传送门 /* 递推DP:官方题解 令Fi,j代表剩下i个人时,若BrotherK的位置是1,那么位置为j的人是否可能获胜 转移的时候可以枚举当前轮指定的数是什么,那么就可以计算出当前位置j的人在剩下i − 1个人时的位置 (假设BrotherK所处的位置是1),然后利用之前计算出的F值判定此人是否可能获胜 时间复杂度为O(n3) dp[i][j] 表示有i个人,j位置的人是否可能胜利.dp[1][0] = 1; cnt = sum (dp[n][i]); 有最优化子结构,i个人可以由i-1个…
题目传送门 /* 递推DP: 如果a, b, c是等差数列,且b, c, d是等差数列,那么a, b, c, d是等差数列,等比数列同理 判断ai-2, ai-1, ai是否是等差(比)数列,能在O(n)时间求出最长的长度 */ #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; typedef long long ll…