2016CCPC Final I. Mr. Panda and Crystal
作者:互联网
题目大意
总共有魔力值 \(M\) , \(N\) 种水晶, \(K\) 种合成公式,每种水晶还有一个基本信息:
\(0\space p_{i}\) :该种水晶不能够由魔力值直接生成,单价为 \(p_{i}\) 。
\(1\space c_{i} \space p_{i}\) :该种水晶可以消耗 \(c_{i}\) 魔力值生成,单价为 \(p_{i}\) 。
每个合成公式的形式为:
\(x_{i}\space y_{i}\space u_{1}\space v_{1}...\) :表示第 \(x_{i}\) 种水晶可以由 \(y_{i}\) 种水晶一起合成,其中第 \(u_{j}\) 种水晶需要 \(v_{j}\) 个。
求所拥有的魔力值可以制造出的最大水晶价值。
思路
我们可以考虑去求出能够获取某种水晶所需要花费的最小魔力值,然后做一个完全背包来求出最后的答案。对于求出最小魔力值的部分,记 \(d[i]\) 为第 \(i\) 种水晶所需的最小魔力值,于是每个公式可以写成 \(d[x_{i}]=\sum_{j=1}^{y_{i}}v_{j}*d[u_{j}]\) 的形式,我们可以建立一张有向图,如果水晶 \(u\) 的最小魔力值会对水晶 \(v\) 的最小魔力值通过公式 \(id\) 产生影响,那么我们就从 \(u\) 到 \(v\) 连一条权值为 \(id\) 的边,然后我们通过 \(dijkstra\) 来对所有的边,也就是对应的公式进行类似松弛的操作就可以求得了。
代码
#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
#define all(x) x.begin(),x.end()
//#define int LL
//#define lc p*2+1
//#define rc p*2+2
#define endl '\n'
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#pragma warning(disable : 4996)
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
const double eps = 1e-8;
const LL MOD = 1000000007;
const LL mod = 998244353;
const int maxn = 210;
const int maxk = 210;
struct edge {
int to, id;
};
int T, cnt = 0;
int M, N, K;
int t[maxn], c[maxn], p[maxn];
int d[maxn];
priority_queue<PII, vector<PII>, greater<PII>>que;
vector<edge>G[maxn];
int dp[10010];
vector<PII>eq[maxn];
void add_edge(int from, int to, int cost)
{
G[from].push_back({ to,cost });
}
void dijkstra()
{
memset(d, inf, sizeof(d));
for (int i = 1; i <= N; i++)
{
if (t[i])
{
d[i] = c[i];
que.push(PII(d[i], i));
}
}
while (!que.empty())
{
PII p = que.top();
que.pop();
int v = p.second;
if (d[v] < p.first)
continue;
for (int i = 0; i < G[v].size(); i++)
{
edge& e = G[v][i];
int sum = 0;
for (int j = 0; j < eq[e.id].size(); j++)
{
int num = eq[e.id][j].second, ty = eq[e.id][j].first;
if (d[ty] == inf)
{
sum = -1;
break;
}
sum += d[ty] * num;
}
if (sum != -1 && sum < d[e.to])
{
d[e.to] = sum;
que.push(PII(d[e.to], e.to));
}
}
}
}
void solve()
{
dijkstra();
for (int i = 1; i <= N; i++)
{
for (int j = 1; j <= M; j++)
{
if (j >= d[i])
dp[j] = max(dp[j], dp[j - d[i]] + p[i]);
}
}
int ans = 0;
for (int i = 0; i <= M; i++)
ans = max(ans, dp[i]);
cout << "Case #" << cnt << ": " << ans << endl;
}
int main()
{
IOS;
cin >> T;
while (T--)
{
for (int i = 1; i <= N; i++)
G[i].clear();
for (int i = 0; i <= K; i++)
eq[i].clear();
for (int i = 0; i <= M; i++)
dp[i] = 0;
cnt++;
cin >> M >> N >> K;
for (int i = 1; i <= N; i++)
{
cin >> t[i];
if (t[i])
cin >> c[i] >> p[i];
else
cin >> p[i];
}
int x, y, u, v;
for (int i = 1; i <= K; i++)
{
cin >> x >> y;
for (int j = 1; j <= y; j++)
{
cin >> u >> v;
eq[i].push_back(PII(u, v));
add_edge(u, x, i);
}
}
solve();
}
return 0;
}
标签:水晶,space,int,魔力,Crystal,maxn,2016CCPC,Panda,define 来源: https://www.cnblogs.com/Prgl/p/15973657.html