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

原题链接: 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值