战场上一般以摧毁敌方的有生力量为目的,不同的目标,彻底进行摧毁需要消耗不同弹药量,各个目标的杀伤价值也不同。现有一款一次带弹1000(total)发的重机枪,怎样在弹药消耗完时达到最大的战场杀伤效果。
目标 i | 摧毁消耗弹药量(发)n | 杀伤价值 v |
---|---|---|
1 | 200 | 6 |
2 | 600 | 10 |
3 | 100 | 3 |
4 | 300 | 5 |
5 | 450 | 8 |
6 | 150 | 4 |
思路一:
求最优解问题,可以用动态规划来求解。
用OPT(i,j)表示面对第i个目标,弹药剩余量为 j 时的最优解。
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int p[7] = { 0, 200, 600, 100, 300, 450, 150 };
int h[7] = { 0, 6, 10, 3, 5, 8, 4 };
int n = 6, total = 1000;
int m[7][1001];
memset(m, 0, sizeof(m));
for (int i = 1; i <= n; ++i){
for (int j = 1; j <= total; ++j)
if (j >= p[i]){
m[i][j] = max(m[i - 1][j], m[i - 1][j - p[i]] + h[i]);
}
else
m[i][j] = m[i - 1][j];
}
for (int i = 1; i <= n; i++){
for (int j = 1; j <= total; j++)
cout << m[i][j] << ' ';
cout << endl;
}
return 0;
}
思路二:
将v/n(杀伤价值/消耗弹药量)按降序排列,选取前面符合总弹药量要求的目标。
/*
1000
200 600 100 150 300 450
6 10 3 4 5 8
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <map>
#include <functional>
#define ARRAY_MAX 101
#define ROW_MAX 1001
int findBest(int prices[], int vals[], int len, int total)
{
using namespace std;
std::multimap<float, int, greater<float>> M;
for (int i = 0; i < len; i++) {
M.insert(pair<float, int>(float(vals[i]) / float(prices[i]), prices[i]));
}
int res = 0;
for (auto m : M) {
if (total / m.second != 0) {
total -= m.second;
res += int(m.first * float(m.second));
}
}
return res;
}
int main(void)
{
int total = 0, vMax = 0, index = 0, i = 0;
int prices[ARRAY_MAX] = { 0 };
int vals[ARRAY_MAX] = { 0 };
scanf("%d", &total);
do {
scanf("%d", &prices[index++]);
} while (getchar() != '\n');
do {
scanf("%d", &vals[i++]);
} while (getchar() != '\n');
vMax = findBest(prices, vals, index, total);
printf("%d", vMax);
}