【动态规划】【最短路】Codeforces 710E Generate a String
题目链接:
http://codeforces.com/problemset/problem/710/E
题目大意:
问写N个字符的最小花费,写一个字符或者删除一个字符花费A,将当前的字符数量翻倍花费B。
题目思路:
【动态规划】【最短路】
【动态规划】:
如果当前x不是2的倍数,那么一定需要单个字符增加或删除,而这个单个操作越靠后答案越优。
dp(x)=a+min(dp(x-1),dp(x+1))
如果当前x是2的倍数,那么有两种情况,一种是通过翻倍的方式获得,一种是通过累加的方式获得。只要比较翻倍的代价和累加的代价。
如果累加x/2次比翻倍更优,那么之前的x/2个一定是累加得到的(否则至少一次翻倍,而累加x/2次都比一次翻倍优)。
dp(x)=(x/2*a<=b)?x*a:dp(x/2)+b;
【最短路】(比赛的时候写的):
f[x]表示生成x个字符的最小花费。f[x]可以扩展f[x-1],f[x+1],f[x+x]。
加点小优化。不然会T。
我就加了一个在f[x]+a<b的情况下都选择写一个字符。就过了。
动态规划:
1 // 2 //by coolxxx 3 //#include<bits/stdc++.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<string> 7 #include<iomanip> 8 #include<map> 9 #include<memory.h> 10 #include<time.h> 11 #include<stdio.h> 12 #include<stdlib.h> 13 #include<string.h> 14 //#include<stdbool.h> 15 #include<math.h> 16 #define min(a,b) ((a)<(b)?(a):(b)) 17 #define max(a,b) ((a)>(b)?(a):(b)) 18 #define abs(a) ((a)>0?(a):(-(a))) 19 #define lowbit(a) (a&(-a)) 20 #define sqr(a) ((a)*(a)) 21 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b)) 22 #define mem(a,b) memset(a,b,sizeof(a)) 23 #define eps (1e-8) 24 #define J 10 25 #define mod 1000000007 26 #define MAX 0x7f7f7f7f 27 #define PI 3.14159265358979323 28 #define N 20000004 29 using namespace std; 30 typedef long long LL; 31 int cas,cass; 32 int n,m,lll,ans; 33 LL a,b; 34 LL dp(int x) 35 { 36 if(x==0)return 0; 37 if(x==1)return a; 38 if(x&1) 39 { 40 LL x1=dp(x-1),x2=dp(x+1); 41 return (LL)(a+min(x1,x2)); 42 } 43 else if((LL)(x/2*a)<=b)return (LL)(x*a); 44 else return (LL)(b+dp(x>>1)); 45 } 46 int main() 47 { 48 #ifndef ONLINE_JUDGE 49 // freopen("1.txt","r",stdin); 50 // freopen("2.txt","w",stdout); 51 #endif 52 int i,j,k; 53 // for(scanf("%d",&cas);cas;cas--) 54 // for(scanf("%d",&cas),cass=1;cass<=cas;cass++) 55 // while(~scanf("%s",s+1)) 56 while(~scanf("%d",&n)) 57 { 58 scanf("%I64d%I64d",&a,&b); 59 printf("%I64d\n",dp(n)); 60 } 61 return 0; 62 } 63 /* 64 // 65 66 // 67 */
最短路:
1 // 2 //by coolxxx 3 //#include<bits/stdc++.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<string> 7 #include<iomanip> 8 #include<map> 9 #include<memory.h> 10 #include<time.h> 11 #include<stdio.h> 12 #include<stdlib.h> 13 #include<string.h> 14 //#include<stdbool.h> 15 #include<math.h> 16 #define min(a,b) ((a)<(b)?(a):(b)) 17 #define max(a,b) ((a)>(b)?(a):(b)) 18 #define abs(a) ((a)>0?(a):(-(a))) 19 #define lowbit(a) (a&(-a)) 20 #define sqr(a) ((a)*(a)) 21 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b)) 22 #define mem(a,b) memset(a,b,sizeof(a)) 23 #define eps (1e-8) 24 #define J 10 25 #define mod 1000000007 26 #define MAX 0x7f7f7f7f 27 #define PI 3.14159265358979323 28 #define N 20000004 29 using namespace std; 30 typedef long long LL; 31 int cas,cass; 32 int n,m,lll,ans; 33 int q[N]; 34 LL f[N]; 35 LL a,b; 36 bool u[N]; 37 void spfa() 38 { 39 mem(f,14);mem(u,0); 40 int i,x,l=0,r=1; 41 f[1]=a; 42 q[1]=1; 43 for(r=2;r<=n;r++) 44 { 45 if(f[r-1]+a>b)break; 46 q[r]=r; 47 f[r]=f[r-1]+a; 48 } 49 while(l!=r) 50 { 51 x=q[l=(l+1)%N]; 52 u[x]=0; 53 if(x<=n && f[x+x]>f[x]+b) 54 { 55 f[x+x]=f[x]+b; 56 if(!u[x+x]) 57 { 58 u[x+x]=1; 59 q[r=(r+1)%N]=x+x; 60 } 61 } 62 if(x>1 && f[x-1]>f[x]+a) 63 { 64 f[x-1]=f[x]+a; 65 if(!u[x-1]) 66 { 67 u[x-1]=1; 68 q[r=(r+1)%N]=x-1; 69 } 70 } 71 if(x<n && f[x+1]>f[x]+a) 72 { 73 f[x+1]=f[x]+a; 74 if(!u[x+1]) 75 { 76 u[x+1]=1; 77 q[r=(r+1)%N]=x+1; 78 } 79 } 80 } 81 } 82 int main() 83 { 84 #ifndef ONLINE_JUDGE 85 // freopen("1.txt","r",stdin); 86 // freopen("2.txt","w",stdout); 87 #endif 88 int i,j,k; 89 // for(scanf("%d",&cas);cas;cas--) 90 // for(scanf("%d",&cas),cass=1;cass<=cas;cass++) 91 // while(~scanf("%s",s+1)) 92 while(~scanf("%d",&n)) 93 { 94 scanf("%I64d%I64d",&a,&b); 95 spfa(); 96 printf("%I64d\n",f[n]); 97 } 98 return 0; 99 } 100 /* 101 // 102 103 // 104 */