[2018.10.10 T1] 餐館

暫無鏈接

餐館

題目背景

銅企鵝是企鵝餐館的老闆,他正在計劃如何使得自己本年度收益增加。

題目描述

共有nn種食材,一份食材ii需要花tit_i小時不間斷地進行播種,施肥,直至收穫。當然,一份食材ii是可以直接賣掉得到wiw_i塊錢的。
招牌菜共有mm種,一份招牌菜ii需要消耗一定的食材,花TiT_i小時不間斷地來烹飪,叫賣,並最終賣出得到WiW_i塊錢。
整個季度換算下來一共有TmaxT_{max}小時可供你使用,銅企鵝需要在這期間賺到最多的錢,這樣他纔有足夠多的錢來steam剁手,或者氪金手遊

格式
輸入格式

第一行一個整數TT,表示數據組數。
ii表示爲當前數據內行數。
第一行三個整數n,m,Tmaxn, m, T_{max},含義如題所示。
第二行至第n+1n + 1行,每行兩個整數ti1,wi1t_{i−1}, w_{i−1},含義如題所示。
n+2n + 2行至第n+m+1n + m + 1行,每行兩個整數Tin1,Win2T_{i−n−1}, W_{i−n−2},含義如題所示。
n+m+2n + m + 2行至第n+2m+1n + 2m + 1行,每行nn個整數,第jj個數djd_j表示招牌菜inm1i − n − m − 1需要djd_j個食材jj

樣例
樣例輸入

3
1 1 48
2 2000
9 21864 5
4 4 46
17 52
4 36
5 43
16 62
9 31659
1 20431
4 623
1 11961
4 5 3 5
5 4 3 4
3 3 3 3
4 4 5 5
10 0 48
10 41
18 48
2 14
22 65
12 77
7 48
4 85
2 61
24 85
8 34

樣例輸出

53728
410
1464
3

數據範圍
Subtask 分值 nn ≤ mm ≤ TT ≤
11 33 11 11 00
22 2020 11 11 55
33 1010 44 44 55
44 1717 20002000 00 55
55 5050 20002000 20002000 44

對於100%100\%的數據,保證0<ti,TiTmax5000,0wi,Wi1090 < t_i, T_i ≤ T_{max} ≤ 5000, 0 ≤ w_i, W_i ≤ 10^9,每份招牌菜使用的食材的個數總數不超過10510^5

題解

招牌菜也可以看做一個物品,價值爲本身價值,時間爲需要的食材時間之和,最後所有招牌菜和原材料一起做個完全揹包即可。

然而,如果你不加帶buffbuff的讀入優化和輸出優化,是不可能A的。。。

代碼
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int M=5005;
struct sd{ll t,w;}sth[M];
ll dp[M],ans;
int T,n,m,mx,tot;
char c;
inline char nc()
{
    static const int buflen=1e6;
    static char buf[buflen],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,buflen,stdin),p1==p2)?EOF:*p1++;
}
int read()
{
    int r=0,f=1;
    while(!isdigit(c)){if(c=='-')f=-1;c=nc();}
    while(isdigit(c)){r=(r<<1)+(r<<3)+c-'0',c=nc();}
    return r*f;
}
void out(ll x)
{
	if(x>9)out(x/10);
	putchar(x%10+'0');
}
void reset(){memset(dp,ans=tot=0,sizeof(dp));}
void in()
{
	n=read(),m=read(),mx=read();
	for(int i=1,a,b;i<=n;++i)a=read(),b=read(),sth[++tot]=(sd){a,b};
	for(int i=1,a,b;i<=m;++i)a=read(),b=read(),sth[++tot]=(sd){a,b};
	for(int i=1,j,a;i<=m;++i)for(int j=1;j<=n;++j)a=read(),sth[n+i].t+=1ll*a*sth[j].t;
}
void ac()
{
	dp[0]=1;
	for(int i=1;i<=tot;++i)for(int j=sth[i].t;j<=mx;++j)
	if(dp[j-sth[i].t])dp[j]=max(dp[j-sth[i].t]+sth[i].w,dp[j]);
	for(int i=1;i<=mx;++i)ans=max(ans,dp[i]);
	out(ans-1),putchar(10);
}
int main(){for(scanf("%d",&T);T--;)reset(),in(),ac();}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章