#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxx=100002; int day[maxx]; __int64 dp[maxx][2];//dp[i][0]表示第i次出差去上海并回到北京的最小花费,dp[i][1]表示第i次出差去上海没有回到北京的最小花费 __int64 min(__int64 a,__int64 b){ return a<b?a:b; } int main(){ int t,a,b,cnt; scanf("%d",&t); for(int i=1;i<=t;i++){ scanf("%d%d%d",&cnt,&a,&b); for(int j=0;j<cnt;j++){ scanf("%d",&day[j]); } dp[0][0]=(__int64)(2*a+b);//第一次去了回来则要花费来回的路费2*a再加上这一天损失的工资b dp[0][1]=(__int64)(a+b);//第一次去了没有回来则只需要花费去的路费a和这一天损失的工资b for(int j=1;j<cnt;j++){ dp[j][0]=min(dp[j-1][0]+2*a+b,dp[j-1][1]+(day[j]-day[j-1])*b+a);//这里的状态转移不用解释了 很显然 dp[j][1]=min(dp[j-1][0]+a+b,dp[j-1][1]+(day[j]-day[j-1])*b); } printf("Case #%d: ",i); printf("%I64d\n",min(dp[cnt-1][0],dp[cnt-1][1]+a));//最后一次没回来的要加上让他回到北京 然后选择最小的就可以了 } return 0; }

hdu 4011 hdu 4011 hdu 4011 hdu 4011

优化了一下,本题因为状态转移方程是临近状态之间的转移,所以可以改为贪心。代码如下

#include <iostream> #include <cstdio> using namespace std; int s[100002]; __int64 min(__int64 a,__int64 b){ return a<b?a:b; } int main(){ int ca; scanf("%d",&ca); for(int t=1;t<=ca;t++){ int n,a,b; __int64 sum=0; scanf("%d%d%d",&n,&a,&b); for(int i=0;i<n;i++){ scanf("%d",&s[i]); } sum+=a*2+b;//刚开时必须去上海花费a工资b,最后一次必须回北京花费a for(int i=1;i<n;i++){ __int64 x,y; x=(s[i]-s[i-1])*b;//上次不用回去,只需加上延误的时间 y=2*a+b; //表示上次回去,所以先加上回去的费用a sum+=min(x,y);//每次sum记录到上次来到上海的最小花费 } printf("Case #%d: %I64d\n",t,sum); } return 0; }

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐