题意:一个人物有K(K<=7)种技能,每种技能都有bi,ci,di值,表示该技能不能点超过bi次,每点一次加ci,点满bi次有一个附加得分di。然后还有N件武器,武器本身会有能力加成,然后每个武器可能会对应着多种的技能,当你装备了这些武器的时候对应的技能的技能点+1(但是武器的技能点不能重复,也就是如果a武器和b武器都能提高技能1的话,如果你两件都装备了只算一次)。现在这些都给定给你了,问的是假如现在你有X个技能点(X<=35)和最多不能携带超过Y件武器(Y<=100),求你所能获得的最大的分数。

思维的切入口在于K的数量级是7,一下子就能联想到2进制的位压,然后很自然的联想到了武器重复不会增加,所以会选择定义这么一种状态dp[n][y][sta],表示的是前n个物品选了y件达到sta状态(就是K个技能有没被加的位压)的时候所获得的最大的分数(这里先不把满技能点的分算进去)。然后就是for循环更新状态了,n的那一维可以滚动(懒得思考方向了),然后一开始dp[0][0][0]=-1,其他设为-1表示状态不存在。 dp完后我们就完成了第一项操作了。

现在就是点技能点的时候,点技能点的时候我们怎么样才知道最大可以点到多少呢,枚举就可以了!我们定义第二个dps[sta]的数组,这个表示的是如果当前状态为sta,那么我点完技能点的时候所能获得的最大加成,由于每个bi<=5,所以每次求一次sta最多不需要超过6^7(实际上会小一点),所以求完一遍总是够时间的。

接下来就是dps[sta]+dp[N&1][Y][sta]里取最大值了(当然不存在的状态就不要管它了)。

想转移想了我颇久了- -0

#pragma warning(disable:4996)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#define ll long long
#define maxn 120
#define maxk 10
using namespace std; int K, N;
int b[maxk], c[maxk], d[maxk]; int G[maxn][maxk];
int a[maxn]; int X, Y; int dp[2][maxn][1 << 8];
int dps[1 << 8]; int dfs(int sta, int step, int cnt)
{
if (step >= K) return 0;
int cur = 0;
if ((sta >> step) & 1) cur++;
int res = 0;
for (int i = 0; i <= b[step] - cur&&i<=cnt; i++){
if (cur + i == b[step]) res = max(res, dfs(sta, step + 1, cnt - i) + d[step]+i*c[step]);
else res = max(res, dfs(sta, step + 1, cnt - i)+i*c[step]);
}
return res;
} int main()
{
while (cin >> K >> N)
{
for (int i = 0; i < K; i++) scanf("%d%d%d", b + i, c + i, d + i);
memset(G, 0, sizeof(G));
int mi;
for (int i = 0; i < N; i++){
scanf("%d%d", a + i, &mi); int ti;
for (int j = 0; j < mi; j++){
scanf("%d", &ti); G[i][ti - 1] = 1;
}
}
scanf("%d%d", &X, &Y);
memset(dp, -1, sizeof(dp));
dp[0][0][0] = 0;
for (int i = 0; i < N; i++){
memcpy(dp[(i + 1) & 1], dp[i & 1], sizeof(dp[(i + 1) & 1]));
for (int x = 0; x <= Y-1; x++){
for (int sta = 0; sta < (1 << K); sta++){
if (dp[i & 1][x][sta] == -1) continue;
int nsta = sta; int inc = a[i];
for (int j = 0; j < K; j++){
if (G[i][j] && !((sta >> j) & 1)){
inc += c[j];
nsta |= 1 << j;
}
}
dp[(i + 1) & 1][x + 1][nsta] = max(dp[(i + 1) & 1][x + 1][nsta], dp[i & 1][x][sta] + inc);
}
}
}
for (int i = 0; i < 1 << K; i++){
dps[i] = dfs(i, 0, X);
}
for (int i = 0; i < 1 << K; i++){
if (dp[N & 1][Y][i] != -1){
dps[i] += dp[N & 1][Y][i];
}
else dps[i] = -1;
}
int ans = 0;
for (int i = 0; i < 1 << K; i++){
ans = max(ans, dps[i]);
}
cout << ans << endl;
}
return 0;
}

ZOJ3718 Diablo II(状态压缩dp)的更多相关文章

  1. 状态压缩dp poj 3254 hdu5045

    近来感觉状态压缩dp的强大性(灵活利用了二进制运算非常关键). . . 于是做了俩提来看看..毕竟队友是专业的dp.我仅仅是管中窥豹下而已.. 日后有机会再与之玩耍玩耍...ps:假设上天再给我一次机 ...

  2. Codeforces C. A Simple Task(状态压缩dp)

    题目描述:  A Simple Task time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

  3. 状态压缩DP(大佬写的很好,转来看)

    奉上大佬博客 https://blog.csdn.net/accry/article/details/6607703 动态规划本来就很抽象,状态的设定和状态的转移都不好把握,而状态压缩的动态规划解决的 ...

  4. BZOJ1294 洛谷P2566 状态压缩DP 围豆豆

    传送门 题目描述 是不是平时在手机里玩吃豆豆游戏玩腻了呢?最近MOKIA手机上推出了一种新的围豆豆游戏,大家一起来试一试吧游戏的规则非常简单,在一个N×M的矩阵方格内分布着D颗豆子,每颗豆有不同的分值 ...

  5. hoj2662 状态压缩dp

    Pieces Assignment My Tags   (Edit)   Source : zhouguyue   Time limit : 1 sec   Memory limit : 64 M S ...

  6. POJ 3254 Corn Fields(状态压缩DP)

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4739   Accepted: 2506 Descr ...

  7. [知识点]状态压缩DP

    // 此博文为迁移而来,写于2015年7月15日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w6jf.html 1.前 ...

  8. HDU-4529 郑厂长系列故事——N骑士问题 状态压缩DP

    题意:给定一个合法的八皇后棋盘,现在给定1-10个骑士,问这些骑士不能够相互攻击的拜访方式有多少种. 分析:一开始想着搜索写,发现该题和八皇后不同,八皇后每一行只能够摆放一个棋子,因此搜索收敛的很快, ...

  9. DP大作战—状态压缩dp

    题目描述 阿姆斯特朗回旋加速式阿姆斯特朗炮是一种非常厉害的武器,这种武器可以毁灭自身同行同列两个单位范围内的所有其他单位(其实就是十字型),听起来比红警里面的法国巨炮可是厉害多了.现在,零崎要在地图上 ...

随机推荐

  1. Secondary IP Addressing

    Secondary IP Addressing secondary IP addressing. Secondary addressing uses multiple networks or subn ...

  2. 6.Knockout.Js(加载或保存JSON数据)

    前言 Knockout可以实现很复杂的客户端交互,但是几乎所有的web应用程序都要和服务器端交换数据(至少为了本地存储需要序列化数据),交换数据最方便的就是使用JSON格式 – 大多数的Ajax应用程 ...

  3. iOS开发多线程篇—单例模式(ARC)

    iOS开发多线程篇—单例模式(ARC) 一.简单说明: 设计模式:多年软件开发,总结出来的一套经验.方法和工具 java中有23种设计模式,在ios中最常用的是单例模式和代理模式. 二.单例模式说明 ...

  4. 编译QT时出现lib/libQtGui.so: undefined reference to `ts_read_raw'的解决办法

    lib/libQtGui.so: undefined reference to `ts_read_raw' /lib/libQtGui.so: undefined reference to `ts_o ...

  5. win7无线网卡的灯突然不亮了的解决办法

    win7无线网卡的灯突然不亮了,百度了一下,按如下的方法解决了:  WIN7中:右键单击“计算机”,选择“管理”进入“计算机管理”,选择“服务和运用”下的“服务”,然后双击“WLAN AutoConf ...

  6. 【AFNetworking】AFNetworking源码阅读(一)

    1. 前言 2. iOS Example代码结构 3.AFNetworkActivityIndicatorManager 4. UIRefreshControl+AFNetworking 5. AFN ...

  7. 用C语言实现的扑克牌洗牌程序

    一副牌:54张 从0开始排序: 0-12表示黑桃   A 1,2,3,... 10,J,Q,K 13-25表示红桃 A 1,2,3,... 10,J,Q,K 26-38表示草花 A 1,2,3,... ...

  8. SQL SERVER完整、差异和事务日志备份及还原(脚本和GUI实现) [原创]

    一.完整备份.差异备份和事务日志备份的脚本 --完整备份数据库 BACKUP DATABASE Test_Bak TO DISK = 'E:\20150609_75\bak\Test_bak_full ...

  9. <梦断代码>读后感2

    <梦断代码>这本书读了一半,我的心情久久不能平静. 为什么好软件如此难做?这是我本人,我想也是很多人都在苦苦思索的一个问题,虽然没有人能有完全确定的答案,但通过书中的记述,和个人思考,还是 ...

  10. 寻找“水王”--c++

    一.题目与设计思路 三人行设计了一个灌水论坛.信息学院的学生都喜欢在上面交流灌水,传说在论坛上有一个“水王”,他不但喜欢发帖,还会回复其他ID发的每个帖子.坊间风闻该“水王”发帖数目超过了帖子数目的一 ...