第十一届山东省大学生程序设计竞赛(正式赛)
作者:互联网
题意:
一个人去打怪兽,当他打过这个怪兽之后,会损失一定的生命值和疲劳值,并获得一定数量的金币,如果生命值减为零了,人就死了,而如果疲劳值减为零了,就相应的从生命值里扣,问保证这个人活着的前提下,能获得的金币的最大值是多少。
思路:
首先考虑结构体排序用贪心来做,但在分析的过程中我们就发现要考虑的条件实在是太多了,所以基本不太可能用贪心了。然后就考虑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