bzoj 4498: 魔法的碰撞(DP+组合数)
来源:互联网 发布:查询域名注册信息 编辑:程序博客网 时间:2024/05/02 04:24
4498: 魔法的碰撞
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 145 Solved: 88
[Submit][Status][Discuss]
Description
魔法总是令战斗的局面变幻莫测。
然而魔力的碰撞则更是天马行空,甚至会出现无法控制而自取灭亡的情况。
因此,魔力碰撞总是没有办法的办法。
不过在战场上大家可不会想太多了:看到敌人,直接一阵法术秒杀之,规则神马的都是浮云了。因此,必须布阵时就避免可能的魔力碰撞。
设想有一条长度为L的战线,你可以把你的魔法师们安排在战线上的每个格子。每一个魔法师都有一个攻击范围di,排兵时必须保证任意两个魔法师的攻击范围的较大值小于等于它们之间的距离(距离即为它们坐标的差值)。为了更好地迷惑敌人,你须要求出总共有多少种布阵的方案。
Input
第一行两个整数L,n,n代表魔法师个数。
第二行n个数,描述魔法师的攻击范围di。
N≤40,di≤40,L≤1000000
Output
一行,一个整数,代表方案数mod 1000000007的值。
Sample Input
9 3
1 2 4
Sample Output
42
如果当前所有FS的顺序已经确定了,并且它们是紧挨着站的,总共长度为w
那么答案就是C(len-w, n)
可是顺序没有确定,并且不同的顺序w也不一样,不过w很小可以DP
先将所有FS按攻击范围从大小排列(后面解释为什么要排序)
dp[i][j][k]表示已经放了前i个法师,当前权值为j,有k个空位的方案数
一个空位可以放若干个FS
DP时只有三种情况
①当前FS填上一个空位(空位-1),此时对w贡献为0,因是从大到小排序,所以插入后左右两边FS肯定是不用动的
②当前FS放在其中一个空位里(空位不变),此时对w贡献为该FS的攻击范围
③当前FS放在其中一个空位里(空位+1),此时对w贡献为该FS的攻击范围*2
#include<stdio.h>#include<algorithm>using namespace std;#define mod 1000000007#define LL long longLL a[44], dp[44][44][3222], jc[1000005] = {1};LL Pow(LL a, LL b){LL ans;ans = 1;while(b){if(b%2==1)ans = (ans*a)%mod;a = (a*a)%mod;b /= 2;}return ans;}LL C(LL n, LL m) {LL ans;if(n<m)return 0;ans = (jc[n]*Pow((jc[m]*jc[n-m])%mod, mod-2)%mod)%mod;return ans;}int main(void){LL len, n, i, j, k, sum, ans;for(i=1;i<=1000000;i++)jc[i] = jc[i-1]*i%mod;scanf("%lld%lld", &len, &n);for(i=1;i<=n;i++)scanf("%lld", &a[i]);sort(a+1, a+n+1);for(i=1;i<=n/2;i++)swap(a[i], a[n-i+1]);for(i=1;i<=n;i++)a[i]--;dp[0][1][0] = 1;sum = 0;for(i=1;i<=n;i++){sum += a[i];for(j=0;j<=i+1;j++){for(k=0;k<=sum*2;k++){dp[i][j][k] = dp[i-1][j+1][k]*(j+1)%mod;if(j>=1 && k>=a[i])dp[i][j][k] = (dp[i][j][k]+dp[i-1][j][k-a[i]]*j*2)%mod;if(j>=2 && k>=2*a[i])dp[i][j][k] = (dp[i][j][k]+dp[i-1][j-1][k-2*a[i]]*(j-1))%mod;}}}ans = 0;for(i=0;i<=2*sum;i++)ans = (ans+dp[n][0][i]*C(len-i, n))%mod;printf("%lld\n", ans);return 0;}
阅读全文
1 0
- bzoj 4498: 魔法的碰撞(DP+组合数)
- [DP 组合数学] BZOJ 4498 魔法的碰撞
- [BZOJ 4498] 魔法的碰撞
- bzoj 4498 魔法的碰撞
- BZOJ 4498 魔法的碰撞
- 开锁魔法 DP+组合数
- bzoj 1801: [Ahoi2009]chess 中国象棋 (组合数+DP)
- [BZOJ 4584][Apio2016]赛艇:DP+组合数
- bzoj4498 魔法的碰撞
- OpenJudge_P2985 数的组合(DP)
- bzoj 3294: [Cqoi2011]放棋子 (容斥原理+组合数+DP)
- [DP 倍增] BZOJ 4870 [Shoi2017]组合数问题
- 【bzoj 3997】组合数学(DP)
- FZU 1896 神奇的魔法数 数位DP
- BZOJ 3209 花神的数论题 (数位DP)
- bzoj 3209 花神的数论题(数位dp)
- BZOJ 1026: [SCOI2009]windy数 (裸的数位dp)
- BZOJ 3209: 花神的数论题 (数位dp)
- Python与机器学习(一)
- python 装饰器学习
- stm32 cube
- CS234 value iteration/policy iteration
- idea使用
- bzoj 4498: 魔法的碰撞(DP+组合数)
- 在JAVA中线程到底起到什么作用!
- 数据结构-一元多项式操作
- PL/SQL的基本语法结构和案例演示
- 二分图最大匹配(匈牙利算法)整理
- JZOJ 5419. 【NOIP2017提高A组集训10.24】筹备计划
- MATLAB教程(1) MATLAB 基础知识
- 数组的特点,数组的使用,链表的特点,set和list的区别,arrayList,linkedList,的常用方法,set,hashset,
- bzoj2013