题目链接: http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=774&pid=1003

  题目大意: a[i], b[i] | 0 <= i <= n .................... k[j],  p[j] | 0 <= j <= m,  n个魔王, m中法术方式, 每个法术攻击p[j], 消耗k[j]水晶,   每个魔王a[i]生命, b[i]护甲, 攻击必须先打穿护甲, 求杀死所有魔王的最少水晶数。

  解题思路: dp[i][j] 表示一个魔王血量为i 护甲为 j 的时候, 杀死它需要的最少水晶, 哦对了, 水晶无限,  所以就转换成n个完全背包问题, 再加和。

  代码: 下面我的代码有错, 不知道哪儿错了

#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <map>
#include <cstring>
#include <iterator>
#include <cmath>
#include <algorithm>
#include <stack>
#include <deque>
#include <map>#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1const int maxn = 1e5+100;
const int maxm = 1e3 + 100;
const int maxa = 1e3 + 100;
const int maxb = 15;
using namespace std;
const int INF = 0x3fffffff;int a[maxn];
int b[maxn];
int k[maxm];
int p[maxm];
int dp[maxa][maxb]; // dp(i, j)生命值为i , 防御值为 j 的时候消灭它花费最少int main() {int n, m;while( scanf( "%d%d", &n, &m ) == 2 ) {int defend = 0;int attack = 0;int ma = 0;for( int i = 1; i <= n; i++ ) {scanf( "%d%d", a+i, b+i );defend = max( defend, *(b+i) );ma = max( ma, *(a+i) );}for( int i = 1; i <= m; i++ ) {scanf( "%d%d", k+i, p+i );attack = max( attack, *(p+i) );}if( attack <= defend ) {printf( "-1\n" );continue;}for( int i = 0; i <= ma; i++ ) {for( int j = 0; j <= defend; j++ ) {if( i == 0 ) dp[0][j] = 0;else dp[i][j] = INF;}}for( int i = 1; i <= ma; i++ ) {for( int j = 0; j <= defend; j++ ) {for( int t = 1; t <= m; t++ ) {if( j > p[t] ) continue;else if( i - (p[t]-j) >= 0 ) {dp[i][j] = min( dp[i][j], dp[i-(p[t]-j)][j]+k[t] );}else dp[i][j] = min( dp[i][j], dp[0][j]+k[t] );}}}long long res = 0;for( int i = 1; i <= n; i++ ) {res += dp[a[i]][b[i]];}printf( "%lld\n", res );}return 0;
}

View Code

  徐文栋的AC代码:

#include <bits/stdc++.h>
using namespace std;typedef long long LL;
const int maxn = 100100;
const int maxm = 1010;
const int maxp = 10010;
const int maxa = 1010;
const int maxb = 11;
const LL inf = (1LL << 60);
int n, m;
int a[maxn], b[maxn], k[maxm], p[maxm];
LL f[maxa][maxb];signed main() {// freopen("in", "r", stdin);while(~scanf("%d %d",&n,&m)) {for(int i = 0; i < maxa; i++) {for(int j = 0; j < maxb; j++) {f[i][j] = inf;}}for(int i = 0; i < maxb; ++i) f[0][i] = 0;int ha = -1, hb = -1;for(int i = 1; i <= n; i++) {scanf("%d%d",&a[i], &b[i]);ha = max(ha, a[i]);hb = max(hb, b[i]);}for(int i = 1; i <= m; i++) scanf("%d%d",&k[i], &p[i]);for(int i = 1; i <= ha; i++) {for(int j = 0; j <= hb; j++) {for(int x = 1; x <= m; x++) {if(j >= p[x]) continue;if(i + j - p[x] > 0) f[i][j] = min(f[i][j], f[i+j-p[x]][j] + k[x]);else f[i][j] = min(f[i][j], f[0][j] + k[x]);}}}LL ret = 0;bool flag = 0;for(int i = 1; i <= n; i++) {if(f[a[i]][b[i]] == inf) {flag = 1;break;}ret += f[a[i]][b[i]];}if(flag) puts("-1");else printf("%I64d\n", ret);}return 0;
}
Close
BestCoder Contest System 2.0

View Code

  思考: 一开始我想的状态是前i个魔王再加上一个状态来求解, 太天真, 每一个魔王都是独立的, 所以dp方程不管怎么都没有办法转移 ,很难受, 然后我想是不是应该像《劲歌金曲》那样不关心前面的状态, 用滚动数组d[i], i表示血量, 同样面临着无法转移的问题, 后来问了人才知道, 事先预处理每个魔王, 再加和, 自己好蠢。 其实不是蠢的问题, 我想问题就是自己还是没有理清思路, 不能够找到真正和结果相联系的状态, 还得多做题。

转载于:https://www.cnblogs.com/FriskyPuppy/p/7294003.html

百度之星资格赛 1003 度度熊与邪恶大魔王 DP 完全背包相关推荐

  1. 2017百度之星资格赛1003 度度熊与邪恶大魔王(完全背包)

    题意: 度度熊为了拯救可爱的公主,于是与邪恶大魔王战斗起来.邪恶大魔王的麾下有n个怪兽,每个怪兽有a[i]的生命值,以及b[i]的防御力.度度熊一共拥有m种攻击方式,第i种攻击方式,需要消耗k[i]的 ...

  2. 2017百度之星 资格赛1003度度熊与邪恶大魔王

    1003度度熊与邪恶大魔王 Accepts: 1503 Submissions: 9026 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 3 ...

  3. 百度之星资格赛1003 度度熊与邪恶大魔王(dp)--2017

    度度熊与邪恶大魔王 Problem Description 度度熊为了拯救可爱的公主,于是与邪恶大魔王战斗起来. 邪恶大魔王的麾下有n个怪兽,每个怪兽有a[i]的生命值,以及b[i]的防御力. 度度熊 ...

  4. 2017百度之星资格赛—1003度度熊与邪恶大魔王

    其他题目就不发博客了(有些也没做出来!!),感觉这次百度之星资格赛题目数据有毒,吐槽,其他题目也不好说,感觉这个题目正常点. 这个题目我当时想到的就是动态规划,但是评论中很多人说是贪心,我一直不理解, ...

  5. 百度之星资格赛1003 度度熊与邪恶大魔王

    Problem Description 度度熊为了拯救可爱的公主,于是与邪恶大魔王战斗起来. 邪恶大魔王的麾下有n个怪兽,每个怪兽有a[i]的生命值,以及b[i]的防御力. 度度熊一共拥有m种攻击方式 ...

  6. 2017百度之星资格赛 1003 度度熊与邪恶大魔王

    本题我们可以类比背包 背包dp[i][j] 表示再有i个物品下j个空间所获得的最大价值 本题dp[i][j] 可以表示干掉i个血量j个防御力下的最小花费 我们看其实我们就是在不同血量之间转移 如果当前 ...

  7. 2017百度之星 资格赛 1003 度度熊与邪恶大魔王(dp)

    #代码: #include<bits/stdc++.h> #define MAXN 1050using namespace std; int n,m; long long int dp[M ...

  8. 百度之星资格赛 1003 度度熊与邪恶大魔王(二维dp)

    分析 挺好的一道题 dp[i][j]表示打败i颗血j防御力的怪兽需要的最少宝石数 然后就好了,复杂度\(O(n+m*1000*10)\) #include <bits/stdc++.h> ...

  9. (百度之星资格赛) 度度熊与邪恶大魔王 (dp)

    度度熊为了拯救可爱的公主,于是与邪恶大魔王战斗起来. 邪恶大魔王的麾下有n个怪兽,每个怪兽有a[i]的生命值,以及b[i]的防御力. 度度熊一共拥有m种攻击方式,第i种攻击方式,需要消耗k[i]的晶石 ...

最新文章

  1. 使用tmpfs缓存文件提高性能
  2. 机器学习-MNIST数据集-神经网络
  3. 今日代码(200612)--数据录入(python+mysql)
  4. 大学计算机一级计算机应用试题及答案,大学生计算机应用基础试题及答案
  5. Node.js 连接 MySQL 并进行数据库操作 –node.js 开发指南
  6. IDEA中配置Python环境并运行
  7. Ubuntu LVS DR模式生产环境部署
  8. 依据imu姿态角计算z轴倾角_[姿态估计] DenseFusion详解
  9. linux qt自带例子无法,在Qt Creator中,错过了一些例子
  10. 试图将一个数学定理证明到最底层的数哲原理...
  11. 推特难民涌入「长毛象」!这个小众社交平台一夜爆红
  12. Android scroller控件,Android Scroller完全解析
  13. python中赋值语句和判断语句结合_Python 3 学习的第二小节——判断赋值语句与简单循环...
  14. android11用石墨文档,轻协作 | 石墨文档 for Android 版轻体验
  15. 使用HtmlUnit爬取知网论文
  16. 使用vue获取富文本编辑器文字内容前50个字符
  17. OBS 插件开发 之 美颜
  18. android蓝牙支持双向,【玩机攻略】了解蓝牙LDAC,玩转双向蓝牙LDAC
  19. java题库(java题库及答案简答题)
  20. easyui java1234_李炎恢jQuery EasyUI视频教程 下载

热门文章

  1. 卷积核——Roberts、Prewitt、Sobel、Lapacian、DoG、LoG算子
  2. C语言作用域与生存期
  3. 基于Redis实现在线游戏积分排行榜
  4. 坐道机器人xy基因改变yx基因_除了XY,决定性别还有另一种关键基因
  5. 在计算机系统中存储容量最大的设备,计算机系统中存储容量最大的部件是().
  6. PostgreSQL:不支持 10 验证类型
  7. Cesium专栏-空间分析之坡向分析(附源码下载)
  8. javaweb企业员工考勤管理系统案例
  9. win10 电脑找不到WIFI,手机却能连上,问题解决
  10. 歌手详情页:下拉方大歌手图片