方案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\ ...
随机推荐
- 如何使用queue_delayed_work函数
本文转自如何使用queue_delayed_work函数 1. delayed_workqueue主要用在需要延迟处理任务的驱动中,这些驱动的特性主要是不能使用中断. delayed_workqueu ...
- js 中 的 if使用条件
在javascript中,哪些值能作为if的条件呢 1.布尔变量true/false2.数字非0,非NaN/ (0 或NaN) 见下面的例子,莫以为负数就以为if语句为假了. 复制代码代码如下: va ...
- samtools
samtools 用法 samtools <command> [options] command 见以下列表, 每个 command 的 options 也不同 dict faidx in ...
- c++ boost 苹果内购 IAP验证
// 1111.cpp: 定义控制台应用程序的入口点. // #include "stdafx.h" #include <cstdlib> #include <i ...
- 设置默认Browser
电信A库要求android系统中有多个Browser时,开机自动设置一个默认浏览器,而不用弹出选择框让用户手动选择. 监听开机广播Intent.ACTION_BOOT_COMPLETED, 用Pack ...
- putty中查询乱码问题
我们在putty连接Linux时候,有时候查询会出现乱码问题...如下图 这个是因为putty中设置编码字符集的原因..将此换为utf8格式的即可解决 解决后查询如下:
- Mac下Maven安装与配置
Mac下Maven安装与配置 下载maven http://maven.apache.org/download.cgi main->download菜单下的Files 下载后解压在Documen ...
- JS基础-数据类型-运算符和表达式-变量和常量
1.js的基础语法2.js调试 1.F12调出控制台,查看提示错误及其位置. 2.出错时只影响当前代码块,不会影响其他代码块,后续代码块继续执行.3.语法规范 1.js语句:可执行的最小单元 必须以 ...
- canvas 实现圆环效果
var race = document.getElementById('race'); var cxt = race.getContext('2d'); var ang = 0; var speed ...
- tp5中代替tp3.2中的一些方法
U方法 U方法是TP中的生成路由的内置方法,现在这个方法可以完全使用url方法替换 I方法 之前的TP有个I方法用来接收请求参数,目前可以使用input方法替代 C方法 c方法被config方法代替