题目链接
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3956
题意 给出N组Hi Ci 然后 要选出若干个 使得
这个式子的值最大 然后是可以不选的,这个式子的值就是0
思路 因为 Ci 的范围特别小,我们就可以用Ci 来当做容量 进行01背包 其实在做题的时候有一个问题 就是 ci 并不是连续的 如果 给出一组数据 3 10 1 5 1 2 10
那个ci 的最大就是 12
但是 其实有效值 能够选择的 Ci 其实 就是 1 2 12
那么中间的其他数值会不会导致答案错误
其实是没必要担心的
在中间其他值的过程中 Hi 是上一组的数据 也就是说 在Hi 相同的情况下 这些选不到的Ci的情况下 按那个式子得出的值是更低的,也就是说不会对答案有什么贡献
最后 FOR 一遍 更新答案
AC代码
#include <cstdio> #include <cstring> #include <ctype.h> #include <cstdlib> #include <cmath> #include <climits> #include <ctime> #include <iostream> #include <algorithm> #include <deque> #include <vector> #include <queue> #include <string> #include <map> #include <stack> #include <set> #include <numeric> #include <sstream> #include <iomanip> #include <limits> #define CLR(a) memset(a, 0, sizeof(a)) #define pb push_back using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; typedef pair <int, int> pii; typedef pair <ll, ll> pll; typedef pair<string, int> psi; typedef pair<string, string> pss; const double PI = 3.14159265358979323846264338327; const double E = exp(1); const double eps = 1e-30; const int INF = 0x3f3f3f3f; const int maxn = 5e2 + 5; const int MOD = 1e9 + 7; int h[maxn], c[maxn]; ll dp[maxn * 100]; int main() { int t; cin >> t; while (t--) { int n; scanf("%d", &n); int sum = 0; for (int i = 0; i < n; i++) { scanf("%d%d", &h[i], &c[i]); sum += c[i]; } CLR(dp); for (int i = 0; i < n; i++) { for (int j = sum; j >= c[i]; j--) dp[j] = max(dp[j], dp[j - c[i]] + h[i]); } ll ans = 0; for (int i = 1; i <= sum; i++) ans = max(ans, dp[i] * dp[i] - i * dp[i] - i * i); printf("%lld\n", ans); } }转载于:https://www.cnblogs.com/Dup4/p/9433157.html
相关资源:JAVA上百实例源码以及开源项目