思路: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; }