夏令营 -- 简单dp

发布时间:2019年07月07日 阅读:228 次

第一题:https://acm.ecnu.edu.cn/problem/3302/

3302. 打印

题面

统计数据

讨论


单点时限: 2.0 sec


内存限制: 256 MB


印 n 个相同的字符,插入或删除一个字符花费的时间为 x,复制当前整个文本并且粘贴在后面的时间花费为 y,

求完成 n 个字符的打印所需的最小花费时间。

1

2

输入格式


三个整数 n,x,y (1≤n≤107,1≤x,y≤109),整数之间用一个空格分隔。

1

对于不超过 30% 的数据,n≤105。

输出格式


输出一个整数表示答案。

1

样例

Input


8 1 1

1

Output


4

1

Input


8 1 10

1

Output


8

1

解题思路


dp


用数组dp[i]来记录打印 i 个相同字符所需的最小花费时间:

    对于字数 i 个相同字符;

* 由i-1个字符输入1个字符产生;

* 由(i-1)/2 个字符复制粘贴而成+输入1个字符;

* 由(i-1)/2 个字符复制粘贴而成+删除1个字符;

取三者的最小值

    对于偶数 i 个相同字符:

* 由i-1个字符插入一个字符产生;

* 由i/2 个字符复制粘贴而成。

取二者的最小值

1

2

3

4

5

6

7

8

9

10

11

12

13

AC 代码


#include <bits/stdc++.h>


using namespace std;

typedef long long LL; 


const int maxn = 1e7+1;

LL dp[maxn];


LL min3(LL a,LL b,LL c){

    return (a<b?a:b)<c?(a<b?a:b):c;

}


LL sol(int n,int x,int y)

{

    if (n==0) return 0;

    if (n==1) return x;

    dp[1]=x;

    for (int i = 2; i <= n; ++i)

    {

        if (i%2==1) //奇数

            dp[i]=min3(dp[i-1]+x,dp[(i-1)/2]+y+x,dp[(i+1)/2]+y+x);

        else //偶数

            dp[i]=min(dp[i-1]+x, dp[i/2]+y);

    }

    return dp[n];

}


int main()

{

    int n,x,y;

    cin>>n>>x>>y;

    LL ans=sol(n,x,y);

    cout<<ans<<endl;

    return 0;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35



Tag:
相关文章

发表评论: