题意

一个大小为 \(n*m\) 的棋盘,知道每一列放了多少棋子,求有多少摆放方案满足要求。

\(n,m\leq 50\) .

分析

  • 如果是求是否有方案的话可以考虑网络流,行列连边,列容量为 \(b_j\),行容量为 \(m\) 。

  • 考虑转化成一个最小割问题,假设\(S\rightarrow row\) 有 \(i\) 条边,\(column \rightarrow T\) 有 \(j\) 条边,中间显然要断开 \((n-i)*(m-j)\)条边。在这样的情况下左边和右边的边一定是前 \(i\) 小和前 \(j\) 小的边。

  • 发现只要最后 \(\sum{a_i}=\sum{b_i}\) ,且对于排序后的 \(a\) 任意的 \(i\) 满足\(s_i=\sum_{k=1}^{i}{a_i}\) 都比其下限大就一定是合法方案。

  • 下限 \(low\):\(s_i\) 在所有的 \(j\) 的情况下的最大值。如果小于下限就会出现比 \(\sum{b_i}\) 还要小的割,不符合题意。

  • 考虑定义状态 \(f_{i,j,k}\) 表示权值不超过 \(i\),选了 \(j\) 行,和为 \(j\) 的方案数。

  • 转移枚举 \(i\) 选择了 \(x\) 个,然后在剩下的行中选择 \(x\) 行的方案数为 \(\binom{n-j}{x}\) ,要保证对于 \(p\in [0,x]\),有 \((k+p*x)\geq {low}_{j+p}\)

  • 总时间复杂度为 \(O(n^3m^2)\)。

代码

#include<bits/stdc++.h>
using namespace std;
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].last,v=e[i].to)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pb push_back
typedef long long LL;
inline int gi(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
return x*f;
}
template<typename T>inline bool Max(T &a,T b){return a<b?a=b,1:0;}
template<typename T>inline bool Min(T &a,T b){return b<a?a=b,1:0;}
const int N=54,inf=0x3f3f3f3f,mod=1e9 + 7;
int n,m,sum;
int b[N],a[N],c[N][N],f[N][N][N*N];
void add(int &a,int b){a+=b;if(a>=mod) a-=mod;}
int main(){
n=gi(),m=gi();
rep(i,1,m) b[i]=gi(),sum+=b[i];
sort(b+1,b+1+m);
rep(i,1,m) b[i]+=b[i-1]; rep(i,1,n){
int tmp=inf;
rep(j,1,m) Min(tmp,(n-i)*(m-j)+b[j]);
a[i]=sum-tmp;
}
rep(i,0,n){
c[i][0]=1;
rep(j,1,i) c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
} f[0][0][0]=1;
rep(i,0,m)
rep(j,0,n)
rep(k,0,sum){
for(int v=0;j+v<=n&&k+i*v<=sum;++v){
if(a[j+v]>k+i*v) break;
add(f[i+1][j+v][k+i*v],1ll*f[i][j][k]*c[n-j][v]%mod);
}
}
printf("%d\n",f[m+1][n][sum]);
return 0;
}

Wannafly挑战赛26-F-msc的棋盘[最小割转化dp]的更多相关文章

  1. Codeforces 724E Goods transportation(最小割转DP)

    [题目链接] http://codeforces.com/problemset/problem/724/E [题目大意] 每个城市有pi的物品可以运出去卖,si个物品可以买, 编号小的城市可以往编号大 ...

  2. Wannafly挑战赛26-F. msc的棋盘(模型转化+dp)及一类特殊的网络流问题

    题目链接 https://www.nowcoder.com/acm/contest/212/F 题解 我们先考虑如果已知了数组 \(\{a_i\}\) 和 \(\{b_i\}\),如何判断其是否合法. ...

  3. BZOJ 1001 狼抓兔子 (最小割转化成最短路)

    1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 27715  Solved: 7134[Submit][ ...

  4. Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) E - Goods transportation 最大流转最小割转dp

    E - Goods transportation 思路:这个最大流-> 最小割->dp好巧妙哦. #include<bits/stdc++.h> #define LL long ...

  5. bzoj 1001 原图最小割转化为对偶图最短路

    题目大意: 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形 ...

  6. Atcoder Regular Contest 125 E - Snack(最小割转化+贪心)

    Preface: 这是生平第一道现场 AC 的 arc E,也生平第一次经历了 performance \(\ge 2800\)​,甚至还生平第一次被 hb 拉到会议里讲题,讲的就是这个题,然鹅比较尬 ...

  7. [Wannafly挑战赛28][B msc和mcc][预处理+枚举]

    链接:https://ac.nowcoder.com/acm/contest/217/B来源:牛客网 msc和mcc 题目描述 msc和mcc是一对好朋友,有一天他们得到了一个长度为n的字符串s. 这 ...

  8. Wannafly挑战赛26 B 冥土追魂

    首先,证明结果一定是取某些整行,再加上一个多余的一行的前几个. 假如: x1<=x2<=x3<=x4<=x5 y1<=y2<=y3<=y4<=y5 取6 ...

  9. Wannafly挑战赛26题解

    为啥混进了几道不是魔禁的题--出题人太不敬业了-- 传送门 \(A\) 御坂网络 为啥没有番外个体和整体意志呢 暴力模拟就好了,这个要是都打错我干脆滚回去学文化课算了 //minamoto #incl ...

随机推荐

  1. 留言板0.4_model中的数据库(2)

    今天就讲讲:如何将后台数据呈现在HTML页面中,以及url配置时的两点技巧吧. 1.首先在"views.py"中提取出后台数据 def getform(request): mess ...

  2. mysql内存管理

    1 内存管理结构 mysql有自己的内存申请和释放机制 mysql层有mem_root innodb层有mem_heap,mem_pool,buf_pool 它们的结构图如下 2 mem_root m ...

  3. MariaDB数据表操作实例

    1. MariaDB 数据库操作实例 MariaDB>create database class; //创建class数据库 MariaDB>use class; MariaDB>c ...

  4. webservice安全性浅谈

    原文地址:http://www.cnblogs.com/chhuic/archive/2009/11/19/1606109.html 做项目时,经常会用到WebService来通讯,但WebServi ...

  5. USB AUDIO Device CLASS Requests

    写在前面 本文翻译自 USB Device Class Definition for Audio Devices 1998年版.主要是鄙人个人使用,所以只挑对我有用的翻译.有些我认为不是很重要的可能就 ...

  6. PyCharm导入模块报No model named

    PyCharm导入模块报No model named 引言 在PyCharm中同目录下import其他模块,出现No model named ...的报错,但实际可以运行的情况. 这很可能是因为PyC ...

  7. css常见知识点

    1.内核区分 希望某一个浏览器能一统江湖 -ms-transform:rotate(7deg); //-ms代表ie内核识别码 -moz-transform:rotate(7deg); //-moz代 ...

  8. C语言实现输出杨辉三角

    1.倒推法实现输出杨辉三角右半部分,代码如下: #include<stdio.h> int main() { ]; printf("请输入行数n:"); scanf(& ...

  9. SDN2017 第四次作业

    1.阅读 了解SDN控制器的发展 http://www.sdnlab.com/13306.html http://www.docin.com/p-1536626509.html 了解ryu控制器 ht ...

  10. Android-硬件加速

    转载请注明来源:http://blog.csdn.net/goldenfish1919/article/details/36890475 从3.0(API level 11)開始.Android 2D ...