原题链接: C. Dima and Salad
题目大意为: Dima 想要在 n 中水果中选取一些来做沙拉,每种水果都有taste和calory 两种属性值,要做一份水果沙拉必须满足 所选取的水果的 总taste 除以总calory等于定值 k。 在满足这个原则的前提下,希望总taste 尽可能大。
大致思路: 先计算出每种水果 taste 和 calory*k 的差值 diff 即 taste - calory*k,要满足题目中制作沙拉的基本原则只需要使选取水果的 diff 相加为 0 即可。接着就很容易想到用动态规划进行递归求解最大的总taste。
使用数组的实现方式:
#include <cstdio>
#include <string>
#include <algorithm>
using namespace std;
struct abc{
int t, a;
}c[110];
int dp[2][200000];
int main(){
int n, k, i, w, r;
scanf("%d%d", &n, &k);
for (i = 0; i < n; i++) scanf("%d", &c[i].a);
for (i = 0; i < n; i++){
scanf("%d", &c[i].t);
c[i].t = k * c[i].t - c[i].a;
}
r = 0, w = 1;
memset(dp[r], -1, sizeof(dp[r]));
dp[r][100000] = 0;
for (i = 0; i < n; i++){
memset(dp[w], -1, sizeof(dp[w]));
for (int j = 0; j < 200000; j++){
if (dp[r][j] < 0)
continue;
dp[w][j] = max(dp[w][j], dp[r][j]);
int jj = j + c[i].t;
if (jj >= 0 && jj < 200000){
dp[w][jj] = max(dp[w][jj], dp[r][j] + c[i].a);
}
}
swap(w, r);
}
if (dp[r][100000] == 0) dp[r][100000] = -1;
printf("%d\n", dp[r][100000]);
return 0;
}
代码分析:
读入水果 calory 时即变化为 diff。考虑到题目中 n<=100,k<=10,taste<=100,calory<=100,所以 diff 的大致范围是 -10000 — 100000,为了方便思考问题,数组大小开成 200000,把 100000 设为初始值。
代码中的数组 dp[r] 用于存储最新的可能的 diff 值,通过维护一个 记录前一次状态的数组 dp[w] 进行更新。最终如果总的 diff 值没有达到 100000 (对应真正的 diff 值 0),则说明不存在一个满足原则的选择,返回 -1。
使用容器的实现方式:
#include <cstdio>
#include <vector>
#include <algorithm>
#include <deque>
#include <iostream>
#include <cstring>
#include <set>
#include <map>
using namespace std;
int main()
{
int n, k, a[100], b[100], sh = 10000;;
scanf("%d%d", &n, &k);
for(int i = 0; i < n; ++i)
scanf("%d", a + i);
for(int i = 0; i < n; ++i)
scanf("%d", b + i);
vector<int> cur(2 * sh + 1, -1);
cur[sh] = 0;
for(int i = 0; i < n; ++i)
{
vector<int> tmp(2 * sh + 1, -1);
for(int sa = 0; sa <= 2 * sh; ++sa)
if(cur[sa] != -1)
{
tmp[sa] = max(tmp[sa], cur[sa]);
int val = sa + a[i] - k * b[i];
if(0 <= val && val <= 2 * sh)
tmp[val] = max(tmp[val], cur[sa] + a[i]);
}
swap(cur, tmp);
}
printf("%d\n", cur[sh] == 0 ? -1 : cur[sh]);
return 0;
}
数组实现比容器要慢,两者具体执行情况是:数组方式:31 ms 1600 KB
容器方式:15 ms 168 KB