Codeforces 710E - Generate a String

710E - Generate a String

思路:dp。

dp[i]表示产生长度为i的串的最少花费。

边界:dp[1]=x。

如果i是偶数,dp[i]只需要由dp[i-1]或者dp[i/2]转移过来,因为如果是由dp[i+1]转移过来,那么dp[i+1]要对答案产生贡献肯定是由dp[i+2]转移过来,这中间产生了2*x的花费,这种转移等价于dp[i/2+1]转移到dp[i/2]再转移到dp[i],而这种转移所需要的花费更少,只需要x,所以由dp[i+1]转移过来没有必要。

所以dp[i]=min(dp[i-1]+x,dp[i/2]+y)

如果i是奇数,dp[i]可以由dp[i-1]和dp[i+1]转移过来,但是dp[i+1]还未确定,所以考虑dp[i+1]是由什么转移过来,如果dp[i+1]要对答案产生贡献,那么他肯定不是由dp[i]转移过来,由之前偶数的结论可知,他只能由dp[(i+1)/2]转移过来。

所以dp[i]=min(dp[i-1]+x,dp[(i+1)/2]+y+x)

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))

const int N=1e7+5;
ll dp[N];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n,x,y;
    cin>>n>>x>>y;
    dp[1]=x;
    for(int i=2;i<=n;i++){
        if(i&1)dp[i]=min(dp[i-1]+x,dp[(i+1)/2]+y+x);
        else dp[i]=min(dp[i-1]+x,dp[i/2]+y);
    }
    cout<<dp[n]<<endl;
    return 0;    
} 

 

posted @ 2018-01-17 13:23  Wisdom+.+  阅读(204)  评论(0编辑  收藏  举报