
$SPFA$,优化,$dp$。
写了一个裸的$SPFA$,然后加了一点优化就过了,不过要$300$多$ms$。
$dp$的话跑的就比较快了。
$dp[i]$表示输入$i$个字符的最小花费。
首先$dp[i]=dp[i-1]+x$。
其次,如果$i$是个偶数,那么$dp[i]$还可以从$dp[\frac{i}{2}]$推过来。
如果$i$是奇数,那么$dp[i]$还可以从$dp[\frac{i}{2}]$和$dp[\frac{i}{2} + 1]$推过来。
$SPFA$:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-;
void File()
{
freopen("D:\\in.txt","r",stdin);
freopen("D:\\out.txt","w",stdout);
} int n;
LL x,y;
LL a[];
bool f[]; int main()
{
scanf("%d%lld%lld",&n,&x,&y); memset(a,-,sizeof a); a[]=; a[n]=n*x;
queue<int>Q; Q.push(); f[]=; while(!Q.empty())
{
int h=Q.front(); Q.pop(); f[h]=; if(h+<=n)
{
if(a[h+]==-||a[h]+x<a[h+])
{
a[h+]=a[h]+x;
if(f[h+]==) { Q.push(h+); f[h+]=; }
}
} if(h->=)
{
if(a[h-]==-||a[h]+x<a[h-])
{
a[h-]=a[h]+x;
if(f[h-]==) { Q.push(h-); f[h-]=; }
}
} LL cost=min(h*x,y);
if(*h<=n)
{
if(a[*h]==-||a[h]+cost<a[*h])
{
a[*h]=a[h]+cost;
if(f[*h]==) { Q.push(*h); f[*h]=; }
}
} else
{
if(a[n]==-) a[n]=a[h]+y+x*(*h-n);
else a[n]=min(a[n],a[h]+y+x*(*h-n));
}
} printf("%lld\n",a[n]);
return ;
}
$dp$:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-;
void File()
{
freopen("D:\\in.txt","r",stdin);
freopen("D:\\out.txt","w",stdout);
} int n; LL x,y,dp[]; int main()
{
scanf("%d%lld%lld",&n,&x,&y);
for(int i=;i<=n;i++)
{
dp[i]=dp[i-]+x;
if(i%==) dp[i]=min(dp[i],dp[i/]+y);
else
{
dp[i]=min(dp[i],dp[i/+]+y+x);
dp[i]=min(dp[i],dp[i/]+x+y);
}
}
printf("%lld\n",dp[n]);
return ;
}