题意:要输入n个字符'a',有两种操作,一种是输入或删除一个'a',耗时x;另一种是把当前的整个文本复制粘贴,耗时y。求最少时间。
考虑dp,用d[i]表示输入n个字符的最少时间,其边界条件d[0]=0。
当i为偶数时,
对于任意的i>=2,我们考虑最后一步操作,最后一步操作如果是输入一个字符,那么就有d[i]=d[i-1]+x。
最后一步操作如果是复制粘贴,那么就有d[i]=d[i/2]+y。
即d[i]=min(d[i-1]+x,d[i/2]+y)
当i为奇数时,如果最后一步操作是输入一个字符,同样有d[i]=d[i-1]+x。
但是如果最后一步是复制粘贴的话,因为i是奇数,所以就没办法直接复制粘贴了。
这里有两种选择,
一种是从d[i/2]的状态复制粘贴一遍,然后再插入一个字符。
即d[i]=d[i/2]+x+y
另一种是从d[i/2+1]的状态复制粘贴一遍,然后再删除一个字符。
即d[i]=d[i/2+1]+x+y
所以当i为奇数时,有d[i]=min(d[i-1]+x,d[i/2]+x+y,d[i/2+1]+x+y)
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1e7+10;
const int inf=0x3f3f3f3f;
typedef long long ll;
ll d[maxn];
int main()
{
ll n,x,y;
scanf("%I64d%I64d%I64d",&n,&x,&y);
d[0]=0;
for(int i=1;i<=n;i++)
{
if(i&1) d[i]=min(d[i-1]+x,min(d[i/2]+y+x,d[i/2+1]+y+x));
else d[i]=min(d[i-1]+x,d[i/2]+y);
}
printf("%I64d\n",d[n]);
}