Codeforces Round #214 (Div. 2) C: Dima and Salad 想减肥?吃沙拉

来源:互联网 发布:zookeeper启动 linux 编辑:程序博客网 时间:2024/04/29 00:25

原题链接: C. Dima and Salad

题目大意为: Dima 想要在 n 中水果中选取一些来做沙拉,每种水果都有tastecalory两种属性值,要做一份水果沙拉必须满足  所选取的水果的 总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