标签:
5
1
1 3
3 2
4 3
2 3
1 4
153
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<cmath> using namespace std; int N,S,dp[5005],f[5005],t[5005],sumt[5005],sumf[5005]; void print(){ puts(""); for(int i=1;i<=N+1;i++) printf("%d ",dp[i]); puts(""); } int main(){ // freopen("01.txt","r",stdin); memset(dp,127,sizeof(dp)); scanf("%d%d",&N,&S); for(int i=1;i<=N;i++) scanf("%d%d",&t[i],&f[i]); for(int i=N;i>=0;i--){ sumt[i]=sumt[i+1]+t[i]; sumf[i]=sumf[i+1]+f[i]; } /* for(int i=1;i<=N;i++) printf("%d ",sumt[i]); ** puts(""); ** for(int i=1;i<=N;i++) printf("%d ",sumf[i]); */ // print(); dp[N+1]=0; for(int i=N;i>=0;i--){ for(int j=i+1;j<=N+1;j++){ dp[i]=min(dp[i],dp[j]+sumf[i]*(sumt[i]-sumt[j]+S)); } // print(); } printf("%d\n",dp[1]); return 0; }同样理解了很久题解,不说了,说多了都是泪
还有,我竟然把f数组和dp数组混了!!
以下是转载的题解
用dp[i]表示完成i..n任务的最小费用。
但是计算的时候并不知道前面的时间,于是可以改变计算的方式。
对于某一批任务来说,他和他后面的所有任务都要承受这一段时间,于是可以把这部分费用不放在之前算,而放在这里一起算。
设sumf和sumt分别为f和t的后缀和。
dp[i]=min{dp[j]+sumf[i]*(sumt[i]-sumt[j]+S)}
即计算的是i..j-1这一段任务对之后造成的影响。
测试的时候出了这样一张图,仅供理解:(此时memset值为0x3f)
还有关于INF无穷大的设定看这里:
标签:
原文地址:http://www.cnblogs.com/radiumlrb/p/5792501.html