• 刷题记录:牛客NC14704美味菜肴


    传送门:牛客

    题目描述:

    题目较长此处省略
    输入:
    1 1 74
    2
    1 502 47
    输出:
    408
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    自我感觉这道题还是挺难处理的(虽然代码不长,但是毕竟四星),经过了这道题感觉自己对于 01 背包 01背包 01背包的理解更上一层楼了

    主要思路:

    1. 感觉每一个人首先看到这道题肯定都会想到01背包,但是感觉直接套又有点问题.首先我们会发现我们的价值是会随着我们的时间改变的,所以假设我们直接套01背包的代码的话就会发现我们的 d p [ t ] dp[t] dp[t]显然不是最优的,因为我们当前的物品放的越早我们的价值就是越高的.但是这个问题也不难解决,只要枚举一遍我们的时间即可
    2. 其次,因为我们的题目中要求的是至少有一个菜肴,并且我们的价值是可以为负的,所以我们应该将我们的dp数组全部赋值为-inf,然后将我们的 d p [ 0 ] = 0 dp[0]=0 dp[0]=0,这样的话就可以保证我们至少应该有一个菜肴会被选进来
    3. 当我们想完前两点之后我们这个代码其实还是有bug的,因为我们的菜肴是与我们的时间有关的,也就是说假设我们从 1 菜肴转移到我们的 2 菜肴 1菜肴转移到我们的2菜肴 1菜肴转移到我们的2菜肴与我们 2 菜肴转移到 1 菜肴 2菜肴转移到1菜肴 2菜肴转移到1菜肴,这两个转移最终的答案肯定是不一样的,但是我们在上述的背包里并没有考虑这一点.所以我们需要考虑这一点.也就是尽量的让更加优的菜肴先放在前面,也就是先进背包
    4. 对于两个物体 A, B, 先取 A 物体比先取 B 物体优
      当且仅当
      a i − b i ∗ c i + a j − b j ∗ ( c i + c j ) a_i -b_i * c_i + a_j - b_j * (c_i + c_j) aibici+ajbj(ci+cj) > > > a j − b j ∗ c j + a i − b i ∗ ( c i + c j ) a_j - b_j * c_j + a_i - b_i * (c_i +c_j) ajbjcj+aibi(ci+cj)

    化解一下就是 b j ∗ c i < b i ∗ c j b_j * c_i < b_i * c_j bjci<bicj
    然后我们直接根据上述sort一下即可

    下面是具体的代码部分:

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    using namespace std;
    typedef long long ll;
    #define inf 0x3f3f3f3f
    #define root 1,n,1
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    inline ll read() {
    	ll x = 0, w = 1;
    	char ch = getchar();
    	for (; ch > '9' || ch < '0'; ch = getchar()) if (ch == '-') w = -1;
    	for (; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
    	return x * w;
    }
    #define maxn 1000000
    #define ll_maxn 0x3f3f3f3f3f3f3f3f
    const double eps = 1e-8;
    int n, m, t;
    ll dp[1000010];int b[maxn];
    struct Food{
    	int j,a,c;
    }food[maxn];
    bool cmp(Food aa,Food bb) {
    	return b[aa.j]*bb.c>b[bb.j]*aa.c;
    }
    int main() {
    	n = read();
    	m = read();
    	t = read();
    	for (int i = 1; i <= n; i++) b[i]=read();
    	for (int i = 1; i <= m; i++) {
    		food[i].j=read();food[i].a=read();food[i].c=read();
    	}
    	sort(food+1,food+1+m,cmp);
    	ll ans=-ll_maxn;
    	memset(dp,-0x3f,sizeof(dp));
    	dp[0]=0;
    	for (int k = 1; k <= m; k++) {
    		for (int i = t; i >= food[k].c; i--) {
    			dp[i] = max(dp[i], dp[i - food[k].c] + food[k].a - i * b[food[k].j]);
    			ans=max(ans,dp[i]);
    		}
    	}
    	cout << ans << endl;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
  • 相关阅读:
    HMS Core音频编辑服务音源分离与空间音频渲染,助力快速进入3D音频的世界
    【Mysql】mysql学习之旅02-DDL数据库定义语言
    lotus-local-net 8MiB v1.17.0 本地测试环境
    设计模式 行为型模式 - 迭代器模式(八)
    C 不再是一种编程语言
    基于springboot+Thymeleaf的校园二手交易平台(附源码获取链接)
    C++11 互斥锁
    pdffactory pro 8中文破解版
    Gartner发布中国人工智能软件市场指南,激烈竞争下走向差异化
    面试经典 150 题 4 —(数组 / 字符串)— 80. 删除有序数组中的重复项 II
  • 原文地址:https://blog.csdn.net/yingjiayu12/article/details/127642983