T1 卡车更新问题 (文件名:truck.pas/c/cpp)
【题目描述】
某人购置了一辆新卡车, 从事个体运输业务. 给定以下各有关数据: R[t], t=0,1,2,...,k, 表示已使用过 t 年的卡车, 再工作一年所得的运费, 它随 t 的增加而减少, k (k≤20) 年后卡车已无使用价值.
U[t]: t=0,1,...,k, 表示已使用过 t 年的卡车, 再工作一年所需的维修费, 它随 t 的增加而增加.
C[t], t=0,1,2,...,k, 表示已使用过 t 年的旧卡车, 卖掉旧车, 买进新车, 所需的净费用, 它随 t 的增加而增加. 以上各数据均为实型, 单位为"万元".
设某卡车已使用过 t 年,
① 如果继续使用, 则第 t+1 年回收额为 R[t]-U[t],
② 如果卖掉旧车,买进新车, 则第 t+1年回收额为 R[0]-U[0]-C[t] .
该运输户从某年初购车日起,计划工作 N (N<=20) 年, N 年后不论车的状态如何,不再工作. 为使这 N 年的总回收额最大, 应在哪些年更新旧车? 假定在这 N年内, 运输户每年只用一辆车, 而且以上各种费用均不改变.
【输入数据】
第 1 行: N (运输户工作年限)
第 2 行: k (卡车最大使用年限, k≤20 )
第 3 行: R[0] R[1] ... R[k]
第 4 行: U[0] U[1] ... U[k]
第 5 行: C[0] C[1] ... C[k]
【输出数据】
第 1 行: W ( N 年总回收额 )
第 2--N+1 行: 每行输出 3 个数据:
年序号 ( 从 1 到 N 按升序输出 );
否更新 ( 当年如果更新,输出 1, 否则输出 0);
当年回收额 ( N 年回收总额应等于 W ).
【吐槽】
临场去掉了输出方案,整个题就水了。(借用Cydiater的话:输出方案就是毒瘤)
用f[i][j]表示前i年,当前车使用了j年的总回收额,则
当j==1时,f[i][j]=max{f[i][j],f[i-1][k]+R[0]-U[0]-C[k]} (1<=k<=min(i-1,m))
否则,f[i][j]=f[i-1][j-1]+R[j-1]-U[j-1] (2<=j<=min(i,m))
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<ctime> 7 #include<algorithm> 8 using namespace std; 9 #define MAXN 30 10 struct node{int flag;double v;}ANS[MAXN]; 11 int n,m; 12 double ans,R[MAXN],U[MAXN],C[MAXN],f[MAXN][MAXN]; 13 inline int read() 14 { 15 int x=0,f=1; char ch=getchar(); 16 while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();} 17 while(isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();} 18 return x*f; 19 } 20 double Max(double a,double b) {if(a>b) return a; else return b;} 21 int main() 22 { 23 freopen("truck.in","r",stdin); 24 freopen("truck.out","w",stdout); 25 n=read(); m=read(); 26 for(int i=0;i<=m;i++) scanf("%lf",&R[i]); 27 for(int i=0;i<=m;i++) scanf("%lf",&U[i]); 28 for(int i=0;i<=m;i++) scanf("%lf",&C[i]); 29 f[1][1]=R[0]-U[0]; 30 for(int i=2;i<=n;i++) 31 for(int j=1;j<=min(i,m);j++) 32 { 33 if(j==1) 34 { 35 for(int k=1;k<=min(i-1,m);k++) 36 f[i][j]=Max(f[i][j],f[i-1][k]+R[0]-U[0]-C[k]); 37 } 38 else f[i][j]=f[i-1][j-1]+R[j-1]-U[j-1]; 39 } 40 for(int i=1;i<=m;i++) ans=Max(ans,f[n][i]); 41 printf("%.1lf\n",ans); 42 return 0; 43 }