方案dp。。
最近经常做到组合计数的题目,每当看到这种题目第一反应总是组合数学,然后要用到排列组合公式,以及容斥原理之类的。。然后想啊想,最后还是不会做。。
但是比赛完之后一看,竟然是dp。。例如前几天的口号匹配求方案数的题目,今天的uva4656,以及hdu4248都是这种类型的题目。。
说说uva4565吧。
题意大概意思是:有N种纸牌,G给位置。。然后给定每种纸牌最少排几张,求满足的方案。
这样一来我们怎么划分状态呢?以位置?
不,我们得用纸牌来划分状态,并枚举纸牌之前用了几张
那么用f[i][j]表示前I个纸牌已经满足题意,且总共放了j个位置的方案数。那么 f[i][j] = sigma(f[i-1][k] * c[G - k][j - k]){j - k >= a[i]}
至于为什么是 f[i-1][k] * c[G - k][j - k],我们可以这样理解:
反正总的位置固定,选取的j-k个在剩下的G-k个里选择位置就行了。。(这样不会有问题吧)
hdu4248:
这一题自己懒得写了,转自这个博客http://www.cnblogs.com/sweetsc/archive/2012/07/17/2595189.html
我觉得写得很不错!
题意:有N种石头,每种石头有A1,A2....AN个,现取出一些石头组成序列,求可以组成多少种序列
例如:3种:可以产生:B; G; M; BG; BM; GM; GB; MB; MG; BGM; BMG; GBM; GMB; MBG; MGB.
我们采用动态规划的思想,划分阶段:按照石头种类划分阶段。于是乎,咱们对于第i种石头,相当于之前石头的颜色并不重要,借助高中数学插板法的思想,假如之前的i - 1 种石头,拼出了长 度为len,那么,相当于有len + 1个空,咱们要放第 i 种石头进去,于是乎,转化成了经典问题,我比较得意的总结:
| 球和球 | 盒和盒 | 空盒 | 情况数 |
| 有区别 | 有区别 | 有空盒 | m^n |
| 有区别 | 有区别 | 无空盒 | M!s(n,m) |
| 有区别 | 无区别 | 有空盒 | S(n,1)+s(n,2)+…+s(n,m),n>=m |
| S(n,1)+s(n,2)+…+s(n,n),n<=m | |||
| 有区别 | 无区别 | 无空盒 | S(n,m) |
| 无区别 | 有区别 | 有空盒 | C(n+m-1,n) |
| 无区别 | 有区别 | 无空盒 | C(n-1,m-1) |
| 无区别 | 无区别 | 有空盒 | DP |
| 无区别 | 无区别 | 无空盒 | DP |
这里,第 i 种石头互相没有区别,len + 1个空有序,相当于有区别,可以有空盒,于是,如果咱们从第 i 种中放put个进去,情况数应该是 C(put + len , put)
于是设计状态:DP[i][j] 表示 用前 i 种石头,排出长度为 j 的可能数
然后,状态转移的时候,枚举在阶段 i 放入put个,DP[i + 1][j + put] += DP[i][j] * C(put + j, put) 即可
附上自己奇丑无比的代码:
Uva4656
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <set>
#include <stack>
#include <cmath>
#include <vector>
#include <algorithm>
#define MXN 50100
#define Inf 101010
#define M0(a) memset(a, 0, sizeof(a))
using namespace std;
double c[][], f[][];
int a[], sum[];
int n, m;
void init(){
M0(c);
for (int i = ; i <= ; ++i)
c[i][] = ;
for (int i = ; i <= ; ++i)
for (int j = ; j <= i; ++j)
c[i][j] = c[i-][j] + c[i-][j-];
} void solve(){
M0(sum);
M0(f);
scanf("%d%d", &n, &m);
for (int i = ; i <= m; ++i){
scanf("%d", &a[i]);
sum[i] = sum[i-] + a[i];
}
f[][] = ;
for (int i = ; i <= m; ++i)
for (int j = sum[i]; j <= n; ++j){
for (int k = a[i]; k <= j; ++k)
f[i][j] += f[i-][j-k] * c[n - j + k][k];
}
for (int i = ; i <= n; ++i)
f[m][n] /= m;
printf("%.6lf\n", f[m][n] * 100.00);
} int main(){
// freopen("a.in", "r", stdin);
// freopen("a.out","w", stdout);
int T, cas = ;
scanf("%d", &T);
init();
for (int i = ; i <= T; ++i){
printf("Case #%d: ", i);
solve();
} // fclose(stdin); fclose(stdout);
}
hdu4248
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <set>
#include <stack>
#include <cmath>
#include <vector>
#include <algorithm>
#define MXN 50100
#define Inf 101010
#define P 1000000007
#define M0(a) memset(a, 0, sizeof(a))
using namespace std;
int c[][];
long long f[][];
int n, a[], m, sum[]; void init(){
for (int i = ; i <= ; ++i)
c[i][] = ;
for (int i = ; i <= ; ++i)
for (int j = ; j <= && j <= i; ++j)
c[i][j] = (c[i-][j] + c[i-][j-]) % P;
} void solve(){
m = ;
M0(f);
M0(sum);
for (int i = ; i <= n; ++i){
scanf("%d", &a[i]);
m += a[i];
sum[i] = m;
}
f[][] = ;
long long ans = ;
for (int i = ; i <= n; ++i)
for (int j = ; j <= sum[i]; ++j){
for (int k = ; k <= a[i]; ++k){
if (k > j) break;
f[i][j] = (f[i][j] + f[i-][j-k] * c[j][k]) % P;
}
if (i == n && j) ans = (ans + f[i][j]) % P;
}
printf("%I64d\n", ans);
} int main(){
//freopen("a.in", "r", stdin);
// freopen("a.out","w", stdout);
int T, cas = ;
init();
while (scanf("%d", &n) != EOF){
printf("Case %d: ", ++cas);
solve();
} fclose(stdin); fclose(stdout);
}
方案dp。。的更多相关文章
- NOIP2006金明的预算方案[DP 有依赖的背包问题]
题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”.今 ...
- cf1140E 回文串+染色方案dp
有点硬核的dp..要用到一个结论.. /* 把原串拆成奇偶串,再拆成极大连续的-1串:该串两端都是非-1数,中间都是-1,并且下标要么都是偶数,要么都是技术 然后对所有这些串进行dp,dp[i][0] ...
- BZOJ1079:[SCOI2008]着色方案(DP)
Description 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块. 所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n.相邻两个 ...
- luogu P1417 烹调方案 |dp
题目背景 由于你的帮助,火星只遭受了最小的损失.但gw懒得重建家园了,就造了一艘飞船飞向遥远的earth星.不过飞船飞到一半,gw发现了一个很严重的问题:肚子饿了~ gw还是会做饭的,于是拿出了储藏的 ...
- PS8625替代方案CS5211|CS5211可以替代兼容PS8625方案|DP转LVDS芯片方案
PS8625|Parade普瑞 PS8625|Parade普瑞 PS8625芯片|Parade普瑞 PS8625方案|Parade普瑞 PS8625芯片代理|DP转LVDS|PS8625替代方案CS5 ...
- CS5218替代AG6310方案设计|替代AG6310方案|DP转HDMI 4K30Hz转换方案
AG6310是一款实现显示端DP口转HDMI数据转换器.AG6310是一款单芯片解决方案,通过DP端口连接器传输视频和音频流,其DP1.2支持可配置的1.2和4通道,分别为1.62Gbps.2.7Gb ...
- CapstoneCS5212替代IT6516方案|DP转VGA芯片|替代兼容IT6516
台湾联阳IT6516是一种高性能的DP显示端口到VGA转换器方案芯片.IT6516结合DisplayPort接收器和三重DAC,通过转换功能支持DisplayPort输入和VGA输出.内置Displa ...
- bzoj 1079: [SCOI2008]着色方案 DP
1079: [SCOI2008]着色方案 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 803 Solved: 512[Submit][Status ...
- BZOJ.2660.[BJOI2012]最多的方案(DP)
题目链接 首先我们知道: 也很好理解.如果相邻两项出现在斐波那契表示法中,那它们显然可以合并. 所以我们能得到\(n\)的斐波那契表示,记\(pos[i]\)为\(n\)的斐波那契表示法中,第\(i\ ...
随机推荐
- andorid 数据储存
.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android ...
- poj 2777(线段树+lazy思想) 小小粉刷匠
http://poj.org/problem?id=2777 题目大意 涂颜色,输入长度,颜色总数,涂颜色次数,初始颜色都为1,然后当输入为C的时候将x到y涂为颜色z,输入为Q的时候输出x到y的颜色总 ...
- kali安全工具
http://www.kali.org.cn/ Kali linux下载安装 (27) kali linux是backtrack的最新代号,或者叫新版本的backtrack,欢迎下载使用. 908 / ...
- Vue 不同环境配置相应的 API 地址
我使用的是 Vue + ElementUI 进行构建的项目,在开发过程中,使用的是前后端分离的模式,所以经常会出现多环境配置信息,尤其是 Api 接口地址的配置,如果在代码中使用判断的方式,感觉不友好 ...
- [Robot Framework] Robot Framework用Execute Javascript对XPath表示的元素执行scrollIntoView操作
有些元素需要通过滚动条滚动才能变得可见. 如果这些元素在DOM结构里面存在,可以通过scrollIntoView让其可见,但如果在DOM结构里面不存在那就要通过拖动滚动条让其变的可见. Execute ...
- Aspose.Words给word文档加水印
需求:在一些重要的Word文档需要打印时,添加水印以明出处. 方案:使用Aspose组件给word文档 代码:干货如下 /// <summary> /// Inserts a waterm ...
- mybatis-mysql类型映射
JDBC Type Java Type CHAR String VARCHAR String LONGVARCHAR String NUMERIC java.math.BigDecimal DECIM ...
- BP神经网络的数学常识
输入数据X1-Xn. 输入层和隐层之间的权Wji 隐层的输入数据为:∑iwjixi 隐层的输出数据为:yj = f(∑iwjixi).其中f(x)= 隐层的输入数据为:∑jwkjyj 隐层的输出数据为 ...
- 2019.01.04 bzoj2962: 序列操作(线段树+组合数学)
传送门 线段树基础题. 题意:要求维护区间区间中选择ccc个数相乘的所有方案的和(c≤20c\le20c≤20),支持区间加,区间取负. 由于c≤20c\le20c≤20,因此可以对于每个线段树节点可 ...
- ajax from 提交
$.ajax({ cache: true, type: "POST", url:aj ...