1. 程式人生 > >P1417 烹調方案(DP)

P1417 烹調方案(DP)

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

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

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

下面一行n個整數,ai

下面一行n個整數,bi

下面一行n個整數,ci

輸出格式:
輸出最大美味指數

輸入輸出樣例
輸入樣例#1: 複製
74 1
502
2
47
輸出樣例#1: 複製
408

題解:
這道題看起來是01揹包,但是有需要注意的地方

對於這個我用一種易懂的方式說一下

平常做01揹包的題時,由於i的價值永遠是不變的,所以i討論的順序對結果不影響

但是這道題中,如果你先討論了1號點,再討論第二點,第二點的價值會減小,反之一號點會減小,這兩個哪個更優是不確定的,所以如果你先討論1號點就會錯

由此,需要按優先度對所有點進行排序

程式碼:

    #include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<queue> #include<stack> #include<cstdio> #include<cstring> #include<vector> #include<cmath> #include<map> #define exp 1e-9 #define PI acos(-1.0) #define INF 0x3f3f3f3f using namespace std; typedef long long LL; int f[100001]; struct zx { int a,b,c; }s[100001
]; bool cmp(zx x,zx y) { return x.c*y.b<y.c*x.b; } int main() { int t,n,i,j,maxx=0; scanf("%d%d",&t,&n); for(i=1;i<=n;i++) scanf("%d",&s[i].a); for(i=1;i<=n;i++) scanf("%d",&s[i].b); for(i=1;i<=n;i++) scanf("%d",&s[i].c); sort(s+1,s+1+n,cmp); for(i=1;i<=n;i++) for(j=t;j-s[i].c>=0;j--) f[j]=max(f[j],f[j-s[i].c]+s[i].a-j*s[i].b); for(i=1;i<=t;i++) maxx=max(f[i],maxx); printf("%d\n",maxx); return 0; }