dp专题-简单基础dp-背包
2016-03-01 20:51
344 查看
按照这个做的:http://doc.okbase.net/cc_again/archive/71796.html
hdu
1864 最大报销额 01背包
方法一:
double类型的背包
总数30个、每个最大1000、保留2位有效位。直接把double*100转换为int型的背包
代码
对个数背包,dp[j] = max(dp[j], dp[j-1]+a[i]);
网上的代码能ac但错了的代码,有后效性
这组就过不了
100.00 5
1 A:5
1 B:20
1 C:24
1 A:30
1 A:60
方法二:
搜索
hdu
1864 最大报销额 01背包
方法一:
double类型的背包
总数30个、每个最大1000、保留2位有效位。直接把double*100转换为int型的背包
代码
//看清题目 //double型的01背包 #include #include #include using namespace std; const int N = 3000050; int dp ; int a ; int main(void) { double total; int n; int i, j; while(scanf("%lf%d", &total, &n), n) { int tmp; int cnt = 0; memset(dp, 0, sizeof(dp)); for(j = 0; j < n; j++) { scanf("%d", &tmp); // cin >> tmp; double pricetotal = 0.0; char c, cc; double price; int flag = 1; double A, B, C; A = B = C = 0; for(i = 0; i < tmp; i++) { char c; getchar(); scanf("%c:%lf", &c, &price); if(c == 'A' && A+price <= 600.0) { A += price; } else if(c == 'B' && B+price <= 600.0) { B += price; } else if(c == 'C' && C+price <= 600.0) { C += price; } else flag = 0; } if(flag && A+B+C <= 1000.0) a[cnt++] = (A+B+C)*100; } int v = (total)*100; for(i = 0; i < cnt; i++) { for(j = v; j >= a[i]; j--) { dp[j] = max(dp[j], dp[j-a[i]]+a[i]); } } double ans = dp[v]; printf("%.2lf\n", ans/100.0); } return 0; }
对个数背包,dp[j] = max(dp[j], dp[j-1]+a[i]);
网上的代码能ac但错了的代码,有后效性
这组就过不了
100.00 5
1 A:5
1 B:20
1 C:24
1 A:30
1 A:60
#include #include #include using namespace std; const int N = 100; double a ; double dp ; void debug(int n, double a[]) { for(int i = 0; i < n; i++) { printf("%.2lf ", a[i]); } printf("\n"); } int main(void) { double total; int n; while(~scanf("%lf%d", &total, &n), n) { int i, j; int cnt = 0; memset(a, 0, sizeof(a)); memset(dp, 0, sizeof(dp)); for(i = 0; i < n; i++) { int tmp = 0; int flag = 1; scanf("%d", &tmp); char c; double price; double A, B, C;//三类的总价格 A = B = C = 0; while(tmp--) { getchar(); scanf("%c:%lf", &c, &price); if(c == 'A' && price+A <= 600.0) { A += price; } else if(c == 'B' && price+B <= 600.0) { B += price; } else if(c == 'C' && price+C <= 600.0) { C += price; } else flag = 0; } if(flag && A+B+C <= 1000.0) { a[cnt++] = A+B+C; } } for(i = 0; i < cnt; i++) { for(j = cnt; j >= 1; j--) { if(dp[j-1]+a[i] <= total) dp[j] = max(dp[j], dp[j-1]+a[i]); } } double ans = 0; for(i = 0; i <= cnt; i++) ans = max(ans, dp[i]); printf("%.2lf\n", ans); } return 0; }
方法二:
搜索
//dfs+剪枝 #include #include #include #include using namespace std; const int N = 100; double a ; double sum ; double dfs(double total, int cnt) { double ans; if(cnt == 1) return a[cnt]>total?0:a[cnt]; if(total >= sum[cnt]) return sum[cnt];//剪枝关键,否者时间复杂度为O(2^n) if(a[cnt] == total) ans = a[cnt]; else if(a[cnt] < total) { ans = max(dfs(total-a[cnt], cnt-1)+a[cnt], dfs(total, cnt-1)); } else ans = dfs(total, cnt-1); return ans; } int main(void) { double total; int n; int i, j; while(scanf("%lf%d", &total, &n), n) { int tmp; int cnt = 1; memset(sum, 0, sizeof(sum)); for(j = 0; j < n; j++) { scanf("%d", &tmp); double pricetotal = 0.0; char c, cc; double price; int flag = 1; double A, B, C; A = B = C = 0; for(i = 0; i < tmp; i++) { char c; getchar(); scanf("%c:%lf", &c, &price); if(c == 'A' && A+price <= 600.0) { A += price; } else if(c == 'B' && B+price <= 600.0) { B += price; } else if(c == 'C' && C+price <= 600.0) { C += price; } else flag = 0; } if(flag && A+B+C <= 1000.0) a[cnt++] = (A+B+C); } for(i = 1; i < cnt; i++) { sum[i] = sum[i-1] + a[i]; } printf("%.2lf\n", dfs(total, cnt-1)); } return 0; }
相关文章推荐
- Android粒子效果之雨
- 单链表的逆置和中间结点的查找
- hadoop 集群调度 Azkaban2搭建
- Uva10305——Ordering Tasks
- 二叉树非递归后序遍历
- 1.5-邮件脚本收敛讲解
- String字符串与整数之间的相互转换
- 1.4-邮件脚本讲解
- CSS布局总结
- Hihocoder 1039 : 字符消除
- 面试相关知识点(一)
- Linux学习笔记:vim的初步使用
- 【BZOJ3622】已经没有什么好害怕的了,DP+容斥原理
- Cube 逐点运动到点停止
- Oracle sql查询
- 排序算法代码总结-java版
- Codeforces AIM Tech Round (Div. 2)
- 《leetCode》:Number of 1 Bits
- 1.3-监控子脚本load.sh502.sh讲解
- struts2配置文件struts.xml详解