<span>codeforces710E Generate a String(dp)</span>

题意:

给你一个n(1e7),和x,y

每次可以+1/-1/*2

+-花费x,*2花费y

问你从0变到n的最小花费

思路:

关键是n小啊~

对于每个i,他可能是由i-1加了1

或者i/2乘了2得来的

当前是奇数的时候,可能是i/2*2+1或者(i/2+1)*2-1得来的

前者在i-1加了1里包含了,所以只需要比较后者

/* ***********************************************
Author        :devil
************************************************ */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
#define LL long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define ou(a) printf("%d\n",a)
#define pb push_back
#define mkp make_pair
template<class T>inline void rd(T &x)
{
    char c=getchar();
    x=0;
    while(!isdigit(c))c=getchar();
    while(isdigit(c))
    {
        x=x*10+c-'0';
        c=getchar();
    }
}
#define IN freopen("in.txt","r",stdin);
#define OUT freopen("out.txt","w",stdout);
using namespace std;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int N=1e7+10;
LL dp[N],n,x,y;
int main()
{
    #ifndef ONLINE_JUDGE
    IN
    #endif
    rd(n),rd(x),rd(y);
    dp[1]=x;
    for(int i=2;i<=n;i++)
    {
        dp[i]=dp[i-1]+x;
        if(i&1) dp[i]=min(dp[i],dp[i/2+1]+x+y);
        else dp[i]=min(dp[i],dp[i>>1]+y);
    }
    printf("%I64d\n",dp[n]);
    return 0;
}

 

全部评论

相关推荐

06-27 18:53
门头沟学院 Java
这样才知道自己不适合搞代码,考公去咯
只爱喝白开水:我也发现不适合搞代码,打算转非技术方向了
点赞 评论 收藏
分享
大飞的诡术妖姬:之前看b站多明海有个说法,日本就业竞争非常低的原因不光是毕业学生少,还有很多人干两年不喜欢职场氛围就辞职躺平,位置也空了很多,论吃苦耐劳还得看咱们
点赞 评论 收藏
分享
每晚夜里独自颤抖:这个在牛客不是老熟人了吗
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务