【最短路】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 */

时间: 2024-08-07 04:31:40

【最短路】Codeforces 710E Generate a String的相关文章

(DP)codeforces - 710E Generate a String

原题链接:http://www.codeforces.com/problemset/problem/710/E 题意:一个字符串,开始长度为0,目标长度为n,长度+1或-1需要的时间为x,长度*2需要的时间为y,求0到m需要的最少时间. 分析:这题一上来直接写优先队列bfs,然后很愉快的超内存的了.就想别的方法,想了一会没想清晰,感觉可以用记忆化搜索,就往这上面一想,才发现直接dp就行了. 可以很容易发现,奇数肯定是+1或者通过*2逼近并且+1或-1得到. 而偶数只能在+1和翻倍得到. 所以在奇

CodeForces 710E Generate a String (DP)

题意:给定 n,x,y,表示你要建立一个长度为 n的字符串,如果你加一个字符要花费 x时间,如果你复制前面的字符要花费y时间,问你最小时间. 析:这个题,很明显的DP,dp[i]表示长度为 i 的字符串的最少花费,当 i 是偶数时,要么再加一个字符,要么从i/2中复制,如果为奇数,要么再加1个字符, 要么从i/2先加一个,再复制.即: 奇数 : dp[i] = min(dp[i-1]+x, dp[i/2+1]+y+x); 偶数 : dp[i] = min(dp[i-1]+x, dp[i/2]+y

CodeForces - 710E Generate a String (dp)

题意:构造一个由a组成的串,如果插入或删除一个a,花费时间x,如果使当前串长度加倍,花费时间y,问要构造一个长度为n的串,最少花费多长时间. 分析:dp[i]---构造长度为i的串需要花费的最短时间. 1.构造长度为1的串,只能插入,dp[1] = x. 2.当前串的长度i为偶数,可以 (1)长度为i/2的串加倍:dp[i / 2] + y (2)长度为i-1的串插入一个a:dp[i - 1] + x 3.当前串的长度i为奇数,可以 (1)长度为i/2的串加倍,再加上一个a:dp[i / 2]

codeforces 710E Generate a String(简单dp)

传送门:http://codeforces.com/problemset/problem/710/E 分析: 让你写一个全由"a"组成的长为n的串,告诉你两种操作,第一种:插入一个字母或者删除一个字母需要花费x秒, 第二种:复制现有的串,并加入到原来的穿上,花费y秒,问你最少花费多少时间? 用dp[i]表示需要花费的最少时间,‘ 然后对i为偶数的情况取min(dp[i-1] +x,dp[i/2]+y),当i为奇数时min(dp[i-1] + x, min(dp[i/2+1] + y +

CodeForces 710E Generate a String

$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 comm

【入门dp】E - Generate a String(字符串复制增加删除)

E - Generate a String Time Limit:2000MS     Memory Limit:524288KB     64bit IO Format:%I64d & %I64u Submit Status Practice CodeForces 710E Description zscoder wants to generate an input file for some programming competition problem. His input is a st

Educational Codeforces Round 25 F. String Compression(kmp+dp)

题目链接:Educational Codeforces Round 25 F. String Compression 题意: 给你一个字符串,让你压缩,问压缩后最小的长度是多少. 压缩的形式为x(...)x(...)  x表示(...)这个出现的次数. 题解: 考虑dp[i]表示前i个字符压缩后的最小长度. 转移方程解释看代码,这里要用到kmp来找最小的循环节. 当然还有一种找循环节的方式就是预处理lcp,然后通过枚举循环节的方式. 这里我用的kmp找的循环节.复杂度严格n2. 1 #inclu

Codeforces 56D Changing a String 编辑距离 dp

题目链接:点击打开链接 编辑距离,,== 一边dp一边记录前驱太累,,还是dp后找路径大法好 #include<iostream> #include<cstdio> #include<vector> #include<string.h> using namespace std; #define ll int #define N 1010 char s[N], t[N]; int dp[N][N], n, m; // 0为插入 1为删除 2 3为替换 stru

LeetCode | 1374. Generate a String With Characters That Have Odd Counts生成每种字符都是奇数个的字符串【Python】

LeetCode 1374. Generate a String With Characters That Have Odd Counts生成每种字符都是奇数个的字符串[Easy][Python][字符串] Problem LeetCode Given an integer n, return a string with n characters such that each character in such string occurs an odd number of times. The