任务安排1

题目传送门

一个重要思想:当前的 \(s\) 准备时间对之后的影响可以用后面所有的和 \(\times s\)。利用上述性质,可以提前计算每个分组中 \(s\) 的贡献,消除后效性。\(f[i]\) 表示以 \(i\) 为一段的末尾的答案。由此可以得出方程是 \(f[i]=\min f[j]+(sumc[i]-sumc[j])*sumt[i]+(sumc[n]-sumc[j])*s\),其中 \(j\) 表示以 \(j\) 结尾为一组,\(j+1\sim i\) 为一组。这个方程已经可以用 \(O(n^2)\) 的时间复杂度解决问题了。

#include<bits/stdc++.h>
using namespace std;
#define L(i,l,r) for(int i=l;i<=r;++i)
#define R(i,l,r) for(int i=r;i>=l;--i)
typedef long long ll;
const int N=5010;
int n,s,sumc[N],sumt[N];
ll f[N];
int main(){
    // freopen("1.in","r",stdin);
    // freopen("1.out","w",stdout);
    // ios::sync_with_stdio(0);
    // cin.tie(0);
    // cout.tie(0);
    scanf("%d%d",&n,&s);
    L(i, 1, n){
        int a,b;
        scanf("%d%d",&a,&b);
        sumt[i]=sumt[i-1]+a;
        sumc[i]=sumc[i-1]+b;
    }
    memset(f+1,0x3f,n*8);
    L(i, 1, n)
        L(j, 0, i-1)f[i]=min(f[i],f[j]+1ll*(sumc[i]-sumc[j])*sumt[i]+(sumc[n]-sumc[j])*s);
    printf("%lld",f[n]);
    return 0;
}
posted @ 2023-04-18 22:02  wscqwq  阅读(2)  评论(0编辑  收藏  举报