CodeForces 915C [DFS] CodeForces 158E [DP]

CodeForces 915C Permute Digits

http://codeforces.com/problemset/problem/915/C

Problem Description

You are given two positive integer numbers a and b. Permute (change order) of the digits of a to construct maximal number not exceeding b. No number in input and/or output can start with the digit 0.

It is allowed to leave a as it is.

Input

The first line contains integer a (1 ≤ a ≤ 1018). The second line contains integer b (1 ≤ b ≤ 1018). Numbers don’t have leading zeroes. It is guaranteed that answer exists.

Output

Print the maximum possible number that is a permutation of digits of a and is not greater than b. The answer can’t have any leading zeroes. It is guaranteed that the answer exists.

The number in the output should have exactly the same length as number a. It should be a permutation of digits of a.

Examples

input 1

123
222

output 1

213

input 2

3921
10000

output 2

9321

input 3

4940
5000

output 3

4940

中文大意

已知a,b两个数,求将a的各个数码重排后,能得出的不大于b的最大数。a,b不超过18位,且a可以不变。

分析

首先想到,只需保存a中0~9的数码个数。如果a的位数比b少,直接输出最大可能的a,因为无论其数字位置变化,都有 a<b a < b

对于a,b位数一样的情况,我们一位一位的分析。为保证 a 与 b 最接近,高位一定是尽量取得与 b 一样。因此首先考虑对于倒数第 i 位数(从最高位数起的第 i 位)而a,b,前面的数码都一模一样。此时如果在 a 使用了前面位数的数字后仍然剩下数码 x,且 x 与 b 的第 i 位相等,在这种情况下,为了保证 a<=b a <= b 那么我们先暂时取该位就为 x。 因为前面的数码都一样,我们只用考虑后面能不能得到一个数串使得i位后面的a不比i位后面的b大。怎么判断呢?如果出现一个局面,在取到第j位时,使得a剩下可取的数都比b的第j位数码大,那么这样就一定不能满足题目要求。假如出现这种局面,我们需要返回到前面最近的,且这一位中有剩余数码x,使得x比b的该位小,而我们不得不放弃之前取的与b相同的数码,改为这个数码x,这样后面的位数无论如何取,都有 a<b a < b 了,于是后面就改成可以取的最大数即可。

描述很复杂,实际操作就是用一个bool dfs, 保存局面,然后先看a在该位能否取得与b一样,如果a没有等于b该位的数,且有至少一个小于b该位的数,那么一定行,就直接打印前面与b一样,后面为剩下的最大数串,并返回true。如果a没有小于等于b该位的数可取,那一定不行,返回false。若a可以取得与b该位一样的数,那么先看能不能取一样,如果返回false,则改取得最大的且小于b该位的数,如果有,输出结果,没有就再返回false。

总结

这个题反正方法比较简单,只是有些特判不能忘记,还有就是题上说了,保证有答案。

这个题tag的是dp,大概是有问题吧,不用保存状态,也不会重复取,哪来的动态规划?

在测试程序时,可以用以下几组数据来测:

input

4322
4321

output

4232

input

10000
10000

output

10000

参考代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int d[15],b[25],lena,lenb,res[25];
void solve1()
{
    for(int i=9;i>=0;i--)
    while(d[i]--)
        printf("%d",i);
}
bool f(int digit[15],int cur)
{
    if(cur>lenb)
    {
    for(int i=1;i<cur;i++)
        printf("%d",res[i]);
    return true;
    }
    if(digit[b[cur]])
    {
    digit[b[cur]]--;
        res[cur]=b[cur];
        if(f(digit,cur+1))
        return true;
        digit[b[cur]]++;
    }
    bool flag=false;
    for(int i=b[cur]-1;i>=0;i--)
    if(digit[i])
    {
        flag=true;
        res[cur]=i;
        digit[i]--;
        break;
    }

    if(flag)
    {
    for(int i=1;i<=cur;i++)
        printf("%d",res[i]);
    for(int i=9;i>=0;i--)
        while(digit[i]--)
        printf("%d",i);
    return true;
    }
    return false;   
}
int main()
{
    char a;
    while((a=getchar())>='0')
    d[a-48]++,lena++;
    while((a=getchar())>='0')
    b[++lenb]=a-48;
    if(lenb>lena)
    solve1();
    else
    f(d,1);
    printf("\n");
}

下面一道真正的dp题。

CodeForces 158E Phone Talks

http://codeforces.com/problemset/problem/158/E

Problem Description

Cool J has recently become a businessman Mr. Jackson, and he has to make a lot of phone calls now. Today he has n calls planned. For each call we know the moment ti (in seconds since the start of the day) when it is scheduled to start and its duration di (in seconds). All ti are different. Mr. Jackson is a very important person, so he never dials anybody himself, all calls will be incoming.

Mr. Jackson isn’t Caesar and he can’t do several things at once. If somebody calls him while he hasn’t finished the previous conversation, Mr. Jackson puts the new call on hold in the queue. In this case immediately after the end of the current call Mr. Jackson takes the earliest incoming call from the queue and starts the conversation. If Mr. Jackson started the call at the second t, and the call continues for d seconds, then Mr. Jackson is busy at seconds t, t + 1, …, t + d - 1, and he can start a new call at second t + d. Note that if Mr. Jackson is not busy talking when somebody calls, he can’t put this call on hold.

Mr. Jackson isn’t Napoleon either, he likes to sleep. So sometimes he allows himself the luxury of ignoring a call, as if it never was scheduled. He can ignore at most k calls. Note that a call which comes while he is busy talking can be ignored as well.

What is the maximum number of seconds Mr. Jackson can sleep today, assuming that he can choose an arbitrary continuous time segment from the current day (that is, with seconds from the 1-st to the 86400-th, inclusive) when he is not busy talking?

Note that some calls can be continued or postponed to the next day or even later. However, the interval for sleep should be completely within the current day.

Input

The first input line contains a pair of integers n, k (0 ≤ k ≤ n ≤ 4000) separated by a space. Following n lines contain the description of calls for today. The description of each call is located on the single line and consists of two space-separated integers ti and di, (1 ≤ ti, di ≤ 86400). All ti are distinct, the calls are given in the order of strict increasing ti.

Scheduled times of calls [ti, ti + di - 1] can arbitrarily intersect.

Output

Print a number from 0 to 86400, inclusive — the maximally possible number of seconds for Mr. Jackson to sleep today.

Examples

input

3 2
30000 15000
40000 15000
50000 15000

output

49999

input

5 1
1 20000
10000 10000
20000 20000
25000 10000
80000 60000

output

39999

Note

In the first sample the most convenient way is to ignore the first two calls.

In the second sample it is best to ignore the third call. In this case Mr. Jackson will have b

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值