1 条题解

  • 0
    @ 2025-10-8 16:48:56

    方法一:O(n²)动态规划

    /*
    O(n²)的方法:
    dp[i]:表示前i个任务最小要用多少时间。初始化memset(dp,63,sizeof(dp));dp[0]=0;
    状态方程:dp[i]=min( dp[i], dp[j] + st[i]*(sf[i]-sf[j]) + s*(sf[n]-sf[j]) ); (0<=j<=i-1)(最后一组为 j+1、j+2……i) 
    
    最后答案:dp[n]
    */
    #include<bits/stdc++.h>
    using namespace std;
    const int N=11100;
    int dp[N],f[N],t[N],st[N],sf[N];
    int main()
    {
        int n,s;scanf("%d%d",&n,&s);
        st[0]=0;sf[0]=0; 
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&t[i],&f[i]);
            st[i]=st[i-1]+t[i];
            sf[i]=sf[i-1]+f[i];
        }
        memset(dp,63,sizeof(dp));dp[0]=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=i-1;j>=0;j--)
            {
                dp[i]=min(dp[i],dp[j]+st[i]*(sf[i]-sf[j])+s*(sf[n]-sf[j]));
            }
        }
        printf("%d\n",dp[n]);
        return 0;
    }
    

    方法二:斜率优化动态规划

    /*
    也可以用斜率优化。
    dp[i]=min(dp[i],dp[j]+st[i]*(sf[i]-sf[j])+s*(sf[n]-sf[j]));
    
    dp[i]=dp[j]+st[i]*(sf[i]-sf[j])+s*(sf[n]-sf[j]));
    
    dp[i]-st[i]*sf[i]-s*sf[n]=  dp[j]-s*sf[j]- st[i]*sf[j]
    dp[j]-s*sf[j] =st[i]*sf[j] + dp[i]-st[i]*sf[i]-s*sf[n]
    yj=dp[j]-s*sf[j]
    xj=sf[j]
    k=st[i]
    b=dp[i]-st[i]*sf[i]-s*sf[n]
    
    */
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N=11100;
    LL dp[N],f[N],t[N],st[N],sf[N],s;int q[N];
    double X(int j){ return 1.0*sf[j];}
    double Y(int j){ return 1.0*(dp[j]-s*sf[j]);}
    double K(int j1,int j2){ return ( Y(j1)-Y(j2) ) / (  (X(j1)==X(j2))?1e-9:(X(j1)-X(j2))   )  ;}
    
    int main()
    {
        int n;scanf("%d%lld",&n,&s);
        st[0]=0;sf[0]=0; 
        for(int i=1;i<=n;i++)
        {
            scanf("%lld%lld",&t[i],&f[i]);
            st[i]=st[i-1]+t[i];
            sf[i]=sf[i-1]+f[i];
        }
        int l=1,r=1;q[1]=0;dp[0]=0;
        for(int i=1;i<=n;i++)
        {
            while(l<r && K(q[l],q[l+1])<=st[i] ) l++;
            dp[i]=dp[q[l]]+st[i]*(sf[i]-sf[q[l]])+s*(sf[n]-sf[q[l]]);
            while( l<r && K(q[r-1],q[r] ) >= K(q[r],i) ) r--;
            q[++r]=i;    
        }
        printf("%lld\n",dp[n]);
        return 0;
    }
    
    • 1

    *【动态规划:状态设计DP】任务安排1

    信息

    ID
    252
    时间
    1000ms
    内存
    512MiB
    难度
    3
    标签
    递交数
    70
    已通过
    39
    上传者