2 条题解
-
5
第一步:写标准的程序
#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
设f[i]表示解决完第i个学生的问题后,花费的最小精力,则
按照i和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
- 上传者