2 条题解

  • 5
    @ 2024-1-13 20:26:25

    第一步:写标准的程序

    #include <iostream>
    using namespace std;
    int main(void){
        long long n,k,d;
        register long long *a,*f;
        cin>>n>>k>>d;
        a=new long long[n+1];
        f=new long long[n+1];
        for(register unsigned int i=1;i<=n;i++){
            cin>>a[i];
            f[i]=0x6fffffffffffffff;
        }
        f[1]=a[1];
        for(register unsigned int i=2;i<=n;i++)
            for(register unsigned int j=1;j<i;j++)
                f[i]=min(f[i],f[j]+k+(i-j-1)*d+a[i]);
        cout<<f[n];
        delete[] a;
        delete[] f;
        return 0;
    }
    

    第二步:拆解状态转移方程

    #include <iostream>
    using namespace std;
    int main(void){
        long long n,k,d,val;
        register long long *a,*f;
        cin>>n>>k>>d;
        a=new long long[n+1];
        f=new long long[n+1];
        for(register unsigned int i=1;i<=n;i++){
            cin>>a[i];
            f[i]=0x6fffffffffffffff;
        }
        f[1]=a[1];
        for(register unsigned int i=2;i<=n;i++){
            val=0x6fffffffffffffff;
            for(register unsigned int j=1;j<i;j++)
                val=min(val,f[j]+j*d);
            f[i]=val+k+(i-1)*d+a[i];
        }
        cout<<f[n];
        delete[] a;
        delete[] f;
        return 0;
    }
    

    第三步:找到规律

    val1=f[1]+d

    val2=min(f[1]+d,f[2]+2*d)

    val3=min(f[1]+d,f[2]+2d,f[3]+3d)

    所以val=min(val,f[j]+j*d)

    第四步:完善代码

    #include <iostream>
    using namespace std;
    int main(void){
        long long n,k,d,val;
        register long long *a,*f;
        cin>>n>>k>>d;
        a=new long long[n+1];
        f=new long long[n+1];
        for(register unsigned int i=1;i<=n;i++){
            cin>>a[i];
            f[i]=0x6fffffffffffffff;
        }
        f[1]=a[1];
        val=f[1]-d;
        for(register unsigned int i=2;i<=n;i++){
            f[i]=val+(k+(i-1)*d+a[i]);
            val=min(val,f[i]-i*d);
        }
        cout<<f[n];
        delete[] a;
        delete[] f;
        return 0;
    }
    
    • 4
      @ 2023-10-26 18:02:00

      设f[i]表示解决完第i个学生的问题后,花费的最小精力,则

      f[i]=min(f[k]+k+(ij1)d+a[i]); f[i]=min(f[k]+k+(i-j-1)*d+a[i]);

      按照i和j变量进行分离,

      f[i]=min(f[j]jd)+(k+(i1)d+a[i]); f[i]=min(f[j]-j*d)+(k+(i-1)*d+a[i]);

      i i 相关变量视为常数,和j j 相关变量需要维护最小值

      #include <bits/stdc++.h>
      #define ll long long
      using namespace std;
      const int N=1000005;
      ll a[N],n,m,k,s,t,d,f[N];
      int main(){
      	cin>>n>>k>>d;
      	for (int i=1;i<=n;++i) cin>>a[i];
      	f[1]=a[1];
      	ll mi=f[1]-1*d;
      	for (int i=2;i<=n;++i){
      		f[i]=mi+k+(i-1)*d+a[i];
      		mi=min(mi,f[i]-i*d);
      	}
      	cout<<f[n];
      }
      
      • 1

      信息

      ID
      526
      时间
      1000ms
      内存
      256MiB
      难度
      1
      标签
      (无)
      递交数
      182
      已通过
      122
      上传者