dutacm.club_1089_A Water Problem_(dp)

题意:要获得刚好后n个'k'的字符串,有两种操作,1.花费x秒,增加或删除1个'k'; 2.花费y秒,使个数翻倍。问最少需要多少时间获得这个字符串。

思路:i为偶数个'k',dp[i]=min(dp[i-1]+x,dp[i/2]+y)

   i为奇数个'k',dp[i]=min(dp[i-1]+x,dp[i/2+1]+y+x)

这里需要说明,不可能存在一个w>i/2+1,dp[w]+y+n*x<dp[i/2+1]+y+x,仔细想想可以得到。之前没有注意到这点。

#include <cstdio>
#include <cstring>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<cmath>
using namespace std;
#define N 10000005
#define LL long long

LL dp[N];
int main()
{
    int n,x,y;
    while(scanf("%d%d%d",&n,&x,&y)!=EOF)
    {
        dp[1]=x;
        for(int i=2; i<=n; i++)
            dp[i]=dp[i-1]+x;
        for(int i=2; i<=n; i++)
        {
            dp[i]=min(dp[i],dp[i-1]+x);
            if(i%2==0)
                dp[i]=min(dp[i],dp[i/2]+y);
            else
                dp[i]=min(dp[i],dp[i/2+1]+y+x);
        }
        printf("%lld
",dp[n]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/jasonlixuetao/p/6538861.html