1. 程式人生 > >洛谷 1417 烹調方案

洛谷 1417 烹調方案

一半 mes 數據 希望 來看 printf sin 解釋 clas

咱麽來看看這道題

題目背景

由於你的幫助,火星只遭受了最小的損失。但gw懶得重建家園了,就造了一艘飛船飛向遙遠的earth星。不過飛船飛到一半,gw發現了一個很嚴重的問題:肚子餓了~

gw還是會做飯的,於是拿出了儲藏的食物準備填飽肚子。gw希望能在T時間內做出最美味的食物,但是這些食物美味程度的計算方式比較奇葩,於是絕望的gw只好求助於你了。

題目描述

一共有n件食材,每件食材有三個屬性,ai,bi和ci,如果在t時刻完成第i樣食材則得到ai-t*bi的美味指數,用第i件食材做飯要花去ci的時間。

眾所周知,gw的廚藝不怎麽樣,所以他需要你設計烹調方案使得美味指數最大

輸入輸出格式

輸入格式:

第一行是兩個正整數T和n,表示到達地球所需時間和食材個數。

下面一行n個整數,ai

下面一行n個整數,bi

下面一行n個整數,ci

輸出格式:

輸出最大美味指數

【數據範圍】

對於40%的數據1<=n<=10

對於100%的數據1<=n<=50

所有數字均小於100,000

題意:我就不解釋了,很好懂

乍一看,這不是01背包嗎?哇這麽水的嗎?

仔細一看emmmmm,好像有點不一樣,這裏的價值是隨時間變化而變化的

嗯,好像有點難

咱們來想一下,考慮一下相鄰取的兩個物品x,y的價值

假設現在已經花費的時間為t,這兩個物品分別為x,y

v1=d[x].a-(t+d[x].c)*d[x].b+d[y].a-(t+d[x].c+d[y].c)*d[y].b

v2=d[y].a-(t+d[y].c)*d[y].b+d[x].a-(t+d[y].c+d[x].c)*d[x].b

要是v1>v2

則v1-v2可得

d[x].b*d[y].c>d[y].b*d[x].c

我們可以的出來

一個物品的價值是d[i].c/d[i].b

只要取的順序x比y小則它的價值更優

我們可以按照這個來排序

排完序之後

就是簡單的01背包了

上代碼

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include 
<cstring> using namespace std; typedef long long ll; const int N=500005; struct node { ll a,b,c; }d[100]; ll n,t,dp[N]; bool cmp(node x,node y) { return x.c*y.b<y.c*x.b; } int main() { scanf("%lld %lld",&t,&n); for(ll i=1;i<=n;i++) scanf("%lld",&d[i].a); for(ll i=1;i<=n;i++) scanf("%lld",&d[i].b); for(ll i=1;i<=n;i++) scanf("%lld",&d[i].c); sort(d+1,d+n+1,cmp); for(ll i=1;i<=n;i++) for(ll j=t;j>=d[i].c;j--) { dp[j]=max(dp[j],dp[j-d[i].c]+d[i].a-j*d[i].b); } ll ans=0; for(ll i=0;i<=t;i++) ans=max(dp[i],ans); printf("%lld\n",ans); return 0; }

解決了

洛谷 1417 烹調方案