题目:题目链接

思路:不难看出,合成每个宝石需要消耗一定的魔力值,每个宝石有一定的收益,所以只要我们知道每个宝石合成的最小花费,该题就可以转化为一个背包容量为初始魔力值的完全背包问题,每个宝石的最小花费可以用dijkstra跑一遍最短路算出,路径长度用合成花费表示。

AC代码:

 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue> using namespace std; const int maxn = + ; int vol, n, m, INF; struct node {
int c, w;
vector<int> v;
vector<vector<pair<int, int> > > vec;
friend bool operator < (node a, node b) {
return a.w > b.w;
}
}gem[maxn]; priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>> > q; bool vis[maxn]; void init() {
for(int i = ; i <= n; ++i) {
for(int j = ; j < gem[i].vec.size(); ++j)
gem[i].vec[j].clear();
gem[i].vec.clear();
gem[i].v.clear();
}
while(!q.empty())
q.pop();
memset(vis, false, sizeof(vis));
} bool get_sum(int id) {
int sum, _min = INF;
for(int i = ; i < gem[id].vec.size(); ++i) {
sum = ;
for(int j = ; j < gem[id].vec[i].size(); ++j) {
sum += gem[gem[id].vec[i][j].first].c * gem[id].vec[i][j].second;
if(sum > INF)
sum = INF;
}
_min = min(_min, sum);
}
if(_min < gem[id].c) {
gem[id].c = _min;
return true;
}
return false;
} void dijkstra() {
while(!q.empty()) {
pair<int, int> P = q.top();
q.pop();
if(vis[P.second])
continue;
vis[P.second] = true;
for(int i = ; i < gem[P.second].v.size(); ++i) {
if(!vis[gem[P.second].v[i]] && get_sum(gem[P.second].v[i])) {
q.push(make_pair(gem[gem[P.second].v[i]].c, gem[P.second].v[i]));
}
}
}
} int dp[maxn]; int main()
{
ios::sync_with_stdio();
cin.tie(); int T, t = ;
cin >> T;
while(T--) {
cin >> vol >> n >> m;
INF = vol + ;
init();
int flag;
for(int i = ; i <= n; ++i) {
cin >> flag;
if(flag)
cin >> gem[i].c >> gem[i].w;
else {
cin >> gem[i].w;
gem[i].c = INF;
}
}
int id, num, c, nu;
vector<pair<int, int> > ope;
for(int i = ; i < m; ++i) {
cin >> id >> num;
ope.clear();
for(int j = ; j < num; ++j) {
cin >> c >> nu;
ope.push_back(make_pair(c, nu));
gem[c].v.push_back(id);
}
gem[id].vec.push_back(ope);
} for(int i = ; i <= n; ++i)
if(gem[i].c < INF)
q.push(make_pair(gem[i].c, i)); dijkstra(); memset(dp, , sizeof(dp));
for(int i = ; i <= n; ++i)
for(int v = ; v <= vol; ++v)
if(v >= gem[i].c)
dp[v] = max(dp[v], dp[v - gem[i].c] + gem[i].w); cout << "Case #" << ++t << ": " << dp[vol] << endl;
}
return ;
}

最新文章

  1. C语言 链表排序
  2. 【PHP开发】国外程序员收集整理的 PHP 资源大全
  3. RTP 与RTCP 解释. 含同步时间戳
  4. ALTFP_CONVERT IP使用与仿真
  5. JAVA解析xml的五种方式比较
  6. 时区 : America/Mexico_City 中文:美国中部时间(墨西哥城) 的夏令时
  7. 4G上网卡NIDS拨号之Rmnet驱动
  8. 转:阿里开源Mysql分布式中间件:Cobar
  9. jquery序列化form表单使用ajax提交后处理返回的json数据
  10. 正式学习react(二)
  11. 【Chromium中文文档】Chrom{e,ium}{,OS}中的硬件视频加速
  12. MySQL常用命令总结2
  13. C++基于范围循环(range-based for loop)的陷阱
  14. MySQL 上手教程
  15. 【C语言编程练习】5.10寻找水仙数
  16. thinkPHP中M()和D()的区别
  17. [JAVA] TicTacToe实现Socket通信(一)
  18. python-基础数据类型,集合及深浅copy
  19. 【转】Caffe的solver文件配置
  20. Service 启动Activity

热门文章

  1. es6新语法系列,查找字符串,模板字符串
  2. 第12届D2前端技术论坛
  3. JVM类加载机制二
  4. 整合mybatis分页插件及通用接口测试出现问题
  5. 微软大礼包 | 集合在线学习资源,助你秒变AI达人
  6. python2含有中文路径报错解决办法[\xe4\xbf\xa1\xe6\x81\xaf]
  7. SAP CRM Survey调查问卷的存储模型
  8. Raid 6与raid 5的区别
  9. idea spring boot启动项目上面有红色叉
  10. Python读写文件实际操作的五大步骤