codeforces 543A A. Writing Code(完全背包优化dp )
2015-08-04 09:43
274 查看
题目连接:
codeforces 543A题目大意:
n个程序员写m行代码,第i个程序员写第i行代码会出现viv_i个bug,问写完这m行代码bugs的数量不超过b的方案数。题目分析:
首先容易想到三位的dp:- 定义dp[i][j][k]为前i个程序员写完j行代码出现k个bugs的方案数。
- dp[i][j][k]=∑t=0idp[i−1][j−t][k−t⋅ai]dp[i][j][k] = \sum_{t=0}^i dp[i-1][j-t][k-t\cdot a_i ]
- 但是上面的转移方程式O(n4)\mathcal{O}(n^4)的,会超时,而且空间特别大。
- 所以我们利用完全背包的思想进行优化,将情况划分子问题的时候考虑为当前程序员多写一行和不多写这一行两种情况,那么方程优化为:
- dp[i][j][k]=dp[i−1][j][k]+dp[i][j−1][k−ai]dp[i][j][k] = dp[i-1][j][k] + dp[i][j-1][k-a_i]
- 而且我们发现在更新的过程中去掉i-1这一维度对计算过程没有影响,所以空间也得到了优化,优化过后空间复杂度O(n2)\mathcal{O}(n^2),时间复杂度O(n3)\mathcal{O}(n^3),两方面复杂度都很优良,此题得解。
AC代码:
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #define MAX 507 using namespace std; int n,m,b,mod; int a[MAX]; int dp[MAX][MAX]; int main ( ) { while (~scanf ("%d%d%d%d" , &n , &m , &b , &mod )) { for ( int i = 1 ; i <= n ; i++ ) scanf ( "%d" , &a[i] ); memset ( dp , 0 , sizeof ( dp )); dp[0][0] = 1; for ( int i = 1 ; i <= n ; i++ ) for ( int j = 1 ; j <= m ; j++ ) for ( int k = 0; k <= b ; k++ ) if ( k >= a[i] ) { dp[j][k] += dp[j-1][k-a[i]]; dp[j][k] %= mod; } int ans = 0; for ( int k = 0 ; k <= b ; k++ ) { ans += dp[m][k]; ans %= mod; } printf ( "%d\n" , ans ); } }
相关文章推荐
- 大众点评的大数据实践-CSDN.NET
- (转)推荐系统—从入门到精通(论文选摘)
- hdu 1181 变形课 (dfs)简单搜索
- laravel数据库查询是use方法的使用
- Python 学习 字符串
- 南邮 OJ 1048 图的宽度优先遍历序列
- Executor 的工具类 Executors
- IntelliJ IDEA清空项目缓存
- 机器学习02(贝叶斯)
- [Tyvj 1728]普通平衡树
- js事件委托
- Poj 2594 Treasure Exploration (最小边覆盖+传递闭包)
- 【面试题】百度糯米java工程师面试
- Book---强连通分量
- 南邮 OJ 1047 图的深度优先遍历序列
- 查看ANR
- 小团队的技术管理
- Caffe提取任意层特征并进行可视化
- Block的简单理解
- ASCII、Unicode、GBK和UTF-8字符编码的区别联系