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

洛谷1417 烹調方案

return bottom 思路 ont main 時間 a5-1 names hide

傳送門

題外話:

    由於昨天考DP專題考到懷疑人生

    所以今天決定刷刷基礎題

    先把洛谷普及練習場的DP寫掉

思路:    

  知道它是一個DP題 但是看到題目有一點點懵

  因為物品的價值還和取的時間有關

  仔細想想 發現這題可能有點像國王遊戲

  要找一找規律 用式子推一下

  如下:

1.a[i]-(t+c[i])*b[i]+a[j]-(t+c[i]+c[j])*b[j] >

a[j]-(t+c[j])*b[j]+a[i]-(t+c[j]+c[i])*b[i]

2. a[i]-t*b[i]-c[i]*b[i]+a[j]-t*b[j]

-c[i]*b[j]-c[j]*b[j] >

a[j]-t*b[j]-c[j]*b[j]+a[i]-t*b[i]-c[j]*b[i]-c[i]*b[i]

3.c[i]*b[j]<c[j]*b[i]

  可知 若c[i]*b[j]<c[j]*b[i] 則先取 i 獲得的價值大一些

  所以我們就可以由此先排個序 然後一般的01背包就可以啦

小結:

    求最值的問題可以想想DP

    然後題目裏有一些式子的時候可以考慮推結論找規律來簡化題目

技術分享圖片
 1 #include<iostream>
 2 #include<cstdio>
 3
#include<algorithm> 4 #define ll long long 5 #define go(i,a,b) for(register int i=a;i<=b;i++) 6 #define yes(i,a,b) for(register int i=a;i>=b;i--) 7 #define M 100010 8 using namespace std; 9 int read() 10 { 11 int x=0,y=1;char c=getchar(); 12 while(c<0||c>9) {if(c==-) y=-1
;c=getchar();} 13 while(c>=0&&c<=9) {x=(x<<1)+(x<<3)+c-0;c=getchar();} 14 return x*y; 15 } 16 struct node {ll a,b,c;} d[M]; 17 int T,n; 18 ll f[M],ans; 19 bool cmp(node x,node y) {return x.c*y.b<y.c*x.b;} 20 int main() 21 { 22 T=read();n=read(); 23 go(i,1,n) d[i].a=read(); 24 go(i,1,n) d[i].b=read(); 25 go(i,1,n) d[i].c=read(); 26 sort(d+1,d+n+1,cmp); 27 go(i,1,n) 28 yes(j,T,d[i].c) 29 f[j]=max(f[j],f[j-d[i].c]+d[i].a-j*d[i].b); 30 go(i,1,T) ans=max(ans,f[i]); 31 printf("%lld",ans); 32 return 0; 33 }
View Code

洛谷1417 烹調方案