2019湖南多校第三场

K、sisth sence

theme:future 与peter两人玩纸牌游戏,游戏规则为给两人发相同数目的牌,每轮每人拿出一张牌比大小,future的牌>Peter则future赢,否则peter赢。而future 可以提前知道peter出牌顺序,问future应怎么安排出牌顺序能使赢的次数最大?若有多种出牌方案,则输出字典序最大的序列。

G、what goes up must come down

theme:给定一个长度为n的数组,问最少交换相邻元素几次可以使数组变成前一部分元素成非减序,后面一部分元素成非增序。

D、shortest common non-subsequence

theme:给定两个由0、1组成的字符串,求最短的不是这两个字符串子序列的序列

B、 Arithmetic Progression

theme:给定一个数组,问从数组中抽取任意数量元素,能构成的最长等差数列长度是多少?

solution:先对数组排序。用map[ pair (a[i], a[j]-a[i] ) ]表示以a[i]为首项,a[j]-a[i]为方差的最长等差数列,可知状态转移方差为

 map[ pair (a[i], a[j]-a[i] ) ] = max( map[ pair (a[j], a[j]-a[i] ) ] , 1) + 1。即以第二项为首项,方差一样的最长等差数列。所以dp时从后往前。

C、Emergency Evacation

theme:给定一辆车的座位分布(二维矩阵形式,中间有条过道),有n个乘客,坐在车上不同位置,问最少需要几步他们全都能从exit通道下车。(每次只能往旁边座位或过道移动,或在过道里向后移动)

solution:这题挺巧妙的。如果直接从正面如何下车考虑,会很麻烦,要考虑拥堵情况。但如果从反面转化为上车情况考虑,就是大水题了。将问题转化为:n个人要上车走到各自的位置,一次一个人从通道进去(对应出来时一步一步从exit出),问最少几步。

当一个人上车后,他会往前走到自己座位所在的行,然后到列,所以不会影响下一秒上车的人。所以我们以d[i]算出每个人从上车到走到座位要几步,这几步是不能再少的,同t[i]表示每个人要等几步之后能上车了,可知最终结果为min(d[i]+s[i]),d[i]为定值可求的,而s[i]我们分配的上车顺序(对应原题下车反序)。所以最佳安排方案为d[i]越大的越先进。最后找到min(d[i]+i)即可。

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
#define far(i,n) for(int i=0;i<n;++i)

int a[500005];
int ans[500005];

bool cmp(int a,int b)
{
    return a>b;
}

int main()
{
    int r,s,p;
    cin>>r>>s>>p;
    far(i,p)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        if(y<=s)
            a[i]=r-x+1+s-y+1;
        else
            a[i]=r-x+1+y-s;
    }
//    far(i,p)
//        cout<<a[i]<<" ";
    sort(a,a+p,cmp);
    for(int i=0;i<p;++i)
    {
        ans[i]=a[i]+i;
    }
    cout<<*max_element(ans,ans+p)<<endl;
}

猜你喜欢

转载自blog.csdn.net/wangqianqianya/article/details/88791086