题意:要获得刚好后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; }