1606:【 例 1】任务安排 1
时间限制: 1000 ms 内存限制: 524288 KB【题目描述】
有 N 个任务排成一个序列在一台机器上等待执行,它们的顺序不得改变。机器会把这 N 个任务分成若干批,每一批包含连续的若干个任务。从时刻 0 开始,任务被分批加工,执行第i个任务所需的时间是 Ti。另外,在每批任务开始前,机器需要 S 的启动时间,故执行一批任务所需的时间是启动时间 S 加上每个任务所需时间之和。
一个任务执行后,将在机器中稍作等待,直至该批任务全部执行完毕。也就是说,同一批任务将在同一时刻完成。每个任务的费用是它的完成时刻乘以一个费用系数 Ci 。
请为机器规划一个分组方案,使得总费用最小。
【输入】
第一行是 N。第二行是 S。
下面 N 行每行有一对正整数,分别为 Ti和 Ci ,表示第 i 个任务单独完成所需的时间是 Ti 及其费用系数 Ci 。
【输出】
一个数,最小的总费用。
【输入样例】
5
1
1 3
3 2
4 3
2 3
1 4
【输出样例】
153
【提示】
样例说明:
分组方案为{1,2},{3},{4,5},则完成时间为 {5,5,10,14,14},费用 C={15,10,30,42,56},总费用为 153。
数据范围与提示:
对于全部数据,1≤N≤5000,0≤S≤50,1≤Ti,Ci≤100。
sol:n3 应该很简单,dp[i][j]表示到第i个任务,分了几段(因为时间是有后效性的,处理起来很蛋疼)
#include <bits/stdc++.h> using namespace std; typedef long long ll; inline ll read() { ll s=0; bool f=0; char ch=' '; while(!isdigit(ch)) { f|=(ch=='-'); ch=getchar(); } while(isdigit(ch)) { s=(s<<3)+(s<<1)+(ch^48); ch=getchar(); } return (f)?(-s):(s); } #define R(x) x=read() inline void write(ll x) { if(x<0) { putchar('-'); x=-x; } if(x<10) { putchar(x+'0'); return; } write(x/10); putchar((x%10)+'0'); return; } #define W(x) write(x),putchar(' ') #define Wl(x) write(x),putchar(' ') const int N=5005; const ll inf=0x7fffffffff; int n,S; int Time[N],Cost[N],Time_Qzh[N],Cost_Qzh[N]; ll dp[N][N]; int main() { int i,j,k; R(n); R(S); for(i=1;i<=n;i++) { Time_Qzh[i]=Time_Qzh[i-1]+(Time[i]=read()); Cost_Qzh[i]=Cost_Qzh[i-1]+(Cost[i]=read()); } memset(dp,63,sizeof dp); dp[0][0]=0; for(i=1;i<=n;i++) { for(j=1;j<=i;j++) { for(k=j-1;k<=i-1;k++) { dp[i][j]=min(dp[i][j],dp[k][j-1]+1ll*(Time_Qzh[i]+S*j)*(Cost_Qzh[i]-Cost_Qzh[k])); } } } ll ans=inf; for(i=1;i<=n;i++) ans=min(ans,dp[n][i]); Wl(ans); return 0; } /* input 5 1 1 3 3 2 4 3 2 3 1 4 output 153 */
绞尽脑汁想n2dp做法,肯定是dp[i]表示前i个任务的最小权值,但这样是不行的
后来是这样的(并不知道dp[i]表示什么)
如果j~i是一段的
1):j~n之间要多S的时间 S*(Cost[n]-Cost[j-1]) ----> dp[i]
2):i到j之间的任务结束时间是 Time[i] Time[i]*(Cost[i]-Cost[j-1]) ---->dp[i]
#include <bits/stdc++.h> using namespace std; typedef int ll; inline ll read() { ll s=0; bool f=0; char ch=' '; while(!isdigit(ch)) { f|=(ch=='-'); ch=getchar(); } while(isdigit(ch)) { s=(s<<3)+(s<<1)+(ch^48); ch=getchar(); } return (f)?(-s):(s); } #define R(x) x=read() inline void write(ll x) { if(x<0) { putchar('-'); x=-x; } if(x<10) { putchar(x+'0'); return; } write(x/10); putchar((x%10)+'0'); return; } #define W(x) write(x),putchar(' ') #define Wl(x) write(x),putchar(' ') const int N=5005; int n,S,dp[N]; ll Time[N],Cost[N]; int main() { int i,j; R(n); R(S); for(i=1;i<=n;i++) { Time[i]=Time[i-1]+read(); Cost[i]=Cost[i-1]+read(); } memset(dp,63,sizeof dp); dp[0]=0; for(i=1;i<=n;i++) { for(j=0;j<i;j++) { dp[i]=min(dp[i],dp[j]+Time[i]*(Cost[i]-Cost[j])+S*(Cost[n]-Cost[j])); } } Wl(dp[n]); return 0; } /* input 5 1 1 3 3 2 4 3 2 3 1 4 output 153 */