菜品制作
哎!刚考完CSP周练又来了 T3!
这道题目DP
先说一下f[i][j],表示在 i 时刻,取了前 j 个物品
转移方程:
可以有三种状态:
f[i][j] 如果他自己有值也会参与min的运算
f[i-1][j] 表示不取t[j]和第i-1时刻一样
f[i-1][j-1]+abs(i-t[j]) 表示取t[j] ,加上代价
这三者求代价最小即可
f[i][j]=min(min(f[i][j],f[i-1][j]),f[i-1][j-1]+abs(i-t[j]));
求答案:answer=min(ans,f[i][n]); i:1~2n
注意:
但是如果 i∈[1,n]是不行的,这是因为你不光可以在 [1,n] 中,也可以在更后的时间里将食物取出,也就是说 i∈[1,2n] 才可以。
要将t数组排序,因为我们要在他的最美味时间附近取出食物,换句话来说就是取出食物的顺序是一定不会变的。
程序:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=420,MAX_N=0x3f3f3f3f; 4 int n,t[N],f[N][N]={0}; 5 int main() 6 { 7 scanf("%d",&n); 8 for(int i=1;i<=n;i++) scanf("%d",&t[i]); 9 sort(t+1,t+1+n); 10 memset(f,MAX_N,sizeof f); 11 for(int i=0;i<=n*2;i++) 12 { 13 f[i][0]=0; 14 } 15 for(int i=1;i<=n*2;i++) 16 { 17 for(int j=1;j<=n;j++) 18 { 19 f[i][j]=min(min(f[i][j],f[i-1][j]),f[i-1][j-1]+abs(i-t[j])); 20 } 21 } 22 int ans=MAX_N; 23 for(int i=1;i<=n*2;i++) 24 { 25 ans=min(ans,f[i][n]); 26 } 27 cout<<ans; 28 // f[i][j]=min(min(f[i][j],f[i-1][j]),f[i-1][j-1]+abs(i-t[j])); 29 return 0; 30 }