方案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\ ...
随机推荐
- ubuntu12.04下安装Apache+PHP+MySQL
一.Apache1.安装apache2: sudo apt-get install apache2 2.重启apache2: sudo /etc/init.d/apache2 restart 3.在浏 ...
- [Groovy] 创建Excel,追加Excel
package ScriptLibrary import java.awt.Color import java.awt.GraphicsConfiguration.DefaultBufferCapab ...
- VisualStudio2017密钥(key)我随便输入一下居然通过了?????????!!!!!!!!!!!!
VisualStudio2017密钥(key) 2017年12月30日 14:41:38 阅读数:5048 professional:KBJFW-NXHK6-W4WJM-CRMQB-G3CDH ent ...
- 【WebService】使用CXF开发WebService(四)
CXF简介 Apache CXF = Celtix + XFire,开始叫 Apache CeltiXfire,后来更名为 Apache CXF 了,以下简称为 CXF.CXF 继承了 Celtix ...
- [html]Sublime Text添加插件
今天想在Sublime Text(简称ST)内编写HTML后直接使用浏览器看效果,想添加View in Browser插件,然后遇到奇怪的问题添加插件直接报"找不到有用的插件" 一 ...
- syslog、日志服务器安装、卸载详解、如何安装和卸载EventLog Analyzer
- 使用delphi-cross-socket 开发kbmmw smart http service
前几天我说了使用delphi-cross-socket 扩展kbmmw 的跨平台支持,今天我说一下使用 kbmMWCrossScoketHttpServerTransport 在linux 下支持 k ...
- kbmmw 与extjs 的初次结合
前面写了extjs 的安装,今天写一下kbmmw 与extjs 的结合,参照delphi 产品经理marco文章 . 由于extjs 设计时要读取服务器端的数据,所以先要做一个rest 服务器. 先要 ...
- 747. Largest Number At Least Twice of Others
static int wing=[]() { std::ios::sync_with_stdio(false); cin.tie(NULL); ; }(); class Solution { publ ...
- WebSocket 处理事件
WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议. WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在 W ...