首页 > 代码库 > “玲珑杯”ACM比赛 Round #18 图论你先敲完模板(dp)

“玲珑杯”ACM比赛 Round #18 图论你先敲完模板(dp)

题目链接:http://www.ifrog.cc/acm/problem/1146

题意:中文题

题解:状态转移方程:dp[ i ] = min ( dp[ i ] ,dp[ j ] + 2xi-xj+a ).

dp[1]=0,第一个点需要消耗的能量为0,从第二个点(假设这个点为A)开始,往前遍历一遍点(假设这个点为B)假定B点为休息点,然后直接到A点需要的能量,

依次然后找出最小能量,因为从第二个点依次往后,每次前面的都已经最优了,所以最后n位置得到的就是答案了。

然后有几个注意点INF尽量弄大点,因为数据挺大的,毕竟是以2的指数幂来算的,题目里面还有一个很重要的条件:0≤xi+1−xi≤30。

 1 #include <cstdio> 2 using namespace std; 3  4 const int N=1e5+10; 5 typedef long long LL; 6 LL POW(LL x,LL n){ 7     LL ans=1; 8     while(n>0){ 9         if(n&1) ans=ans*x;10         x=x*x;11         n>>=1;12     }13     return ans;14 }15 LL min(LL a,LL b){16     return (a>b) ? b : a;17 }18 const LL INF=1e18;19 LL x[N],dp[N];20 21 int main(){22     int t;23     scanf("%d",&t);24     while(t--){25         int n,a;26         scanf("%d %d",&n,&a);27         for(int i=1;i<=n;i++){28             scanf("%lld",&x[i]);29             dp[i]=INF;30         }31         dp[1]=0;32         for(int i=2;i<=n;i++){33             for(int j=i-1;j>=1;j--){34                 if(x[i]-x[j]>30) break;35                 dp[i]=min(dp[i],dp[j]+POW(2,x[i]-x[j])+a);36             }37         }38         printf("%lld\n",dp[n]);39     }40     41     return 0;42 }

 

“玲珑杯”ACM比赛 Round #18 图论你先敲完模板(dp)