(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和翻倍得到。

所以在奇数情况下的状态转移方程为dp[i]=min(dp[i-1]+x,dp[i/2]+x+y,dp[i/2+1]+x+y)

偶数情况下的为dp[i]=min(dp[i-1]+x,dp[i/2]+y)



代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<set>
#include<vector>
#include<queue>
#include<map>
#include<list>
#include<bitset>
#include<string>
#include<cctype>
#include<cstdlib>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

namespace Math {
//最大公约数
ll gcd(ll a, ll b) {
    return b == 0 ? a : gcd(b, a%b);
}
//欧拉素数筛
int Euler_prime(int *prime, bool *vis, int maxn) {
    memset(vis, true, sizeof(vis));
    int tot = 0;
    for (int i = 2; i < maxn; i++) {
        if (vis[i]) prime[tot++] = i;
        for (int j = 0; j < tot&&prime[j] * i < maxn; j++) {
            vis[i*prime[j]] = false;
            if (i%prime[j] == 0) break;
        }
    }
    return tot;
}
}

const int inf = 1 << 30;
const ll lnf = 1ll << 60;

//-----upstair is template------//

const int maxn=1e7;
ll dp[maxn];

void solve() {
    int n,x,y;
    scanf("%d%d%d",&n,&x,&y);
    fill(dp,dp+maxn,lnf);
    dp[0]=0;
    for(int i=1;i<=n;i++){
        if(i&1){
            dp[i]=min(dp[i-1]+x,min(dp[i/2+1]+x+y,dp[i/2]+x+y));
        }
        else{
            dp[i]=min(dp[i-1]+x,dp[i/2]+y);
        }
    }
    printf("%I64d\n",dp[n]);
}

int main() {

#ifndef ONLINE_JUDGE
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
#endif
    //iostream::sync_with_stdio(false);
    solve();
    return 0;
}
时间: 2024-12-15 03:18:44

(DP)codeforces - 710E Generate a String的相关文章

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)

题意:给定 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)

传送门: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 +

(dp)CodeForces - 300D Painting Square

Vasily the bear has got a large square white table of n rows and n columns. The table has got a black border around this table.  The example of the initial table at n = 5. Vasily the bear wants to paint his square table in exactly k moves. Each move

【最短路】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的倍数,那么有两种情况,一种是通过翻倍的方式获得,一种是通过累加的方式获得.只要比

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

Codeforces Round #260 (Div. 1) A. Boredom (DP)

题目链接:http://codeforces.com/problemset/problem/455/A A. Boredom time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Alex doesn't like boredom. That's why whenever he gets bored, he comes up with

[LeetCode] Interleaving String(dp)

Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. For example, Given: s1 = "aabcc", s2 = "dbbca", When s3 = "aadbbcbcac", return true. When s3 = "aadbbbaccc", return false. 分析:非常好的DP的训练题,

Ural 1353 Milliard Vasya&#39;s Function(DP)

题目地址:Ural 1353 定义dp[i][j],表示当前位数为i位时,各位数和为j的个数. 对于第i位数来说,总可以看成在前i-1位后面加上一个0~9,所以状态转移方程就很容易出来了: dp[i][j]=dp[i][j]+dp[i][j-1]+dp[i][j-2]+.......+dp[i][j-9]: 最后统计即可. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <