编程语言
首页 > 编程语言> > 第十一届山东省大学生程序设计竞赛(正式赛)

第十一届山东省大学生程序设计竞赛(正式赛)

作者:互联网

H.Adventurer's Guild

题意:

一个人去打怪兽,当他打过这个怪兽之后,会损失一定的生命值和疲劳值,并获得一定数量的金币,如果生命值减为零了,人就死了,而如果疲劳值减为零了,就相应的从生命值里扣,问保证这个人活着的前提下,能获得的金币的最大值是多少。

思路:

首先考虑结构体排序用贪心来做,但在分析的过程中我们就发现要考虑的条件实在是太多了,所以基本不太可能用贪心了。然后就考虑dp,发现dp是可以的,可以看出这个题是01背包的变形,即遇到一个怪兽,你是打还是不打,对应01背包中一个物品选还是不选的情况。

由于这个题是三维的,所以如果不优化的话只能过不到百分之四十的样例,所以我们最后优化掉 i 这一维空间就可以了,注意关键点就是 j 这一维,就是生命值这一维,循环时是大于h[i]的(H到h[i]),

如果用集合角度考虑这个dp问题的话(闫氏dp分析法),即为这个人在生命值大于0时,可以获得的最大金币数。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <string>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <queue>
 7 #include <vector>
 8 #include <map>
 9 #include <set>
10 
11 #define x first
12 #define y second
13 
14 using namespace std;
15 
16 typedef long long LL;
17 typedef pair<int, int>PII;
18 
19 const int N = 1010;
20 
21 LL n, H, S;
22 LL h[N], s[N], w[N];
23 LL f[310][310];
24 
25 int main()
26 {
27     cin >> n >> H >> S;
28 
29     for (int i = 1; i <= n; i++) cin >> h[i] >> s[i] >> w[i];
30 
31     LL res = 0;
32     for (int i = 1; i <= n; i++)
33         for (int j = H; j > h[i]; j--)
34         {
35             for (int k = S; k >= 0; k--)
36             {
37                     if (k >= s[i]) f[j][k] = max(f[j][k], f[j - h[i]][k - s[i]] + w[i]);
38                     else
39                     {
40                         if (j - h[i] - (s[i] - k) > 0) 
41                             f[j][k] = max(f[j][k], f[j - h[i] - (s[i] - k)][0] + w[i]);
42 
43                     }
44                 
45                 res = max(res, f[j][k]);
46             }
47         }
48 
49     cout << res << endl;
50 
51     return 0;
52 }

题意:

给定 一个0/1矩阵C ,构造两个矩阵 A , B ,其中 1 形成了完整的不分散的一块四连通块,并且对于 C 中所有位置,若是 1,则 A , B 对应位置必须都是 1,否则  A , B 之中必须有一个这个位置为 0 。 保证C阵的边框都是0 。

思路:

 

标签:竞赛,int,res,LL,第十一届,max,程序设计,include,dp
来源: https://www.cnblogs.com/yctql/p/14760105.html