Codeforces Round 892 (Div. 2)

  • Post author:
  • Post category:其他




Codeforces Round 892 (Div. 2)



A United We Stand

给定长度为



n

n






n





的数组

a

,可以将

a

中元素添加到空数组

b



c

中,满足两个数组均非空,且

c

中的元素不是

b

中元素的约数。若不能满足输出

-1


c

中的元素不是

b

中元素的约数,即



b

i

  

%
  

c

j

0

b_i \;\% \;c_j \neq 0







b










i




















%





c










j








































=









0





可以将

a

中元素从大到小排序,将所有最大的元素放进

c

中,其余元素放入b中即满足要求。若

b

为空,则输出

-1

const int N = 110;
int n, a[N];

void solve()
{
    vector<int> b, c;
    cin >> n;
    for(int i = 0; i < n; i ++) cin >> a[i];
    sort(a, a + n, [&](int a, int b){return a > b;});	// 从大到小排序
    for(int i = 0; i < n; i ++)
    {
        if(a[i] == a[0])    c.push_back(a[i]);		// 将所有最大值放入C数组
        else    b.push_back(a[i]);
    }
    if(b.empty())
    {
        cout << "-1\n";
        return ;
    }
    cout << b.size() << " " << c.size() << endl;
    for(auto p : b) cout << p << " ";
    cout << endl;
    for(auto p : c) cout << p << " ";
    cout << endl;
}



B Olya and Game with Arrays



n

个数组,最多可以将一个整数从一个数组移动到另一个数组。整数只能从一个数组中移动一次,但整数可以多次添加到一个数组中。对于每个数组找到其中的最小值,然后将这些值相加,求结果的最大值。

要使得最小值尽量大,可以移动每个数组的最小值,那么每个数组对答案的贡献就变成了次小值。将所有最小值插入次小值最小的数组内,可以最小化影响。

取出每个数组的最小值和次小值,将

次小值的最小值



最小值的最小值

取较小值,加上其余所有的次小值。

void solve()
{
    vector<int> minn, lst;
    int n;
    cin >> n;
    for(int i = 0; i < n; i ++)
    {
        int len;
        cin >> len;
        vector<int> a(len);
        for(int i = 0; i < len; i ++) cin >> a[i];
        sort(a.begin(), a.end());
        minn.push_back(a[0]);
        if(len >= 2)    lst.push_back(a[1]);
    }
    sort(minn.begin(), minn.end());
    sort(lst.begin(), lst.end());
    lst[0] = min(lst[0], minn[0]);
    ll ans = 0;
    for(auto p : lst)   ans += p;
    cout << ans << endl;
}



C Another Permutation Problem

成本为



Σ

i

=

1

n

p

i

i

m

a

x

j

=

1

n

p

j

j

\Sigma_{i=1}^np_i \cdot i-max_{j=1}^np_j\cdot j







Σ











i


=


1









n



















p










i





























i













ma



x











j


=


1









n



















p










j





























j





,找出长度



n

n






n





的所有排列中的最大成本。

先打表找个规律

void solve(int len)
{
    vector<int> a(len), b;
    int ans = 0;
    for(int i = 1; i <= len; i ++)  a[i - 1] = i;
    do{
        int res = 0, tmp = 0;
        for(int i = 0; i < len; i ++)   res += a[i] * (i + 1), tmp = max(tmp, a[i] * (i + 1));
        res -= tmp;
        if(res > ans)    ans = max(ans, res), b = a;
    }while(next_permutation(a.begin(), a.end()));
    cout << ans << endl;
    for(auto p : b) cout << p << " ";
    cout << endl;
}
n ans permutation
2 2 2 1
3 7 1 3 2
4 17 1 2 4 3
5 35 1 2 5 4 3
6 62 1 2 3 6 5 4
7 100 1 2 3 4 7 6 5
8 152 1 2 3 4 8 7 6 5
9 219 1 2 3 4 5 9 8 7 6
10 303 1 2 3 4 5 6 10 9 8 7

通过打表可以发现,后面一部分数翻转时答案最大,排列长度最大为250,可以枚举要翻转的数量

void solve()
{
    ll ans = 0;
    int n;
    cin >> n;
    vector<int> a(n);
    for(int i = 0; i < n; i ++) a[i] = i + 1;
    for(int len = 1; len <= n; len ++)    // 枚举要翻转的长度
    {
        ll res = 0, tmp = 0;
        for(int i = 0; i < n - len; i ++)		// 正序部分
            res += a[i] * (i + 1), tmp = max(tmp, a[i] * (i + 1) * 1ll);	// *1ll转换为ll类型
        for(int i = n - len, j = n; i < n; i ++, j --)	// 逆序部分
            res += a[i] * j, tmp = max(tmp, a[i] * j * 1ll);
        res -= tmp;
        ans = max(ans, res);
    }
    cout << ans << endl;
}



D Andrey and Escape from Capygrad

当处于线段



[

l

,

r

]

[l,r]






[


l


,




r


]





上,那么便可以传送到线段



[

a

,

b

]

[a,b]






[


a


,




b


]





上,



l

a

b

r

l\leq a\leq b\leq r






l













a













b













r





。有若干条线段,给定起始位置问最院能传送到哪里

假如当前位置位于



(

b

,

r

]

(b,r]






(


b


,




r


]





就没有必要再传送了,所以有效传送区间为



[

l

,

b

]

[l,b]






[


l


,




b


]





处理出所有的传送区间,进行区间合并,那么在所有的独立区间内都可以任意传送。

二分查找起始位置位于哪个区间左端点的右边,假如起始点在传送区间内就传送到区间的右端点,否则无法传送。

typedef long long ll;
typedef pair<int, int> PII;

vector<PII> vt;

void merge(vector<PII> &segs)	// 区间合并
{
	sort(segs.begin(), segs.end());
	vector<PII> res;
	int st = -2e9, ed = -2e9;
	for(auto seg : segs)
	{
		if(ed < seg.first)
		{
			if(st != -2e9)	res.push_back({st, ed});
			st = seg.first, ed = seg.second;
		}
		else	ed = max(ed, seg.second);
	}
	if(st != -2e9)	res.push_back({st, ed});
	segs = res;
}

bool check(int p, int x)
{
    if(x >= vt[p].first)    return true;
    return false;
}

int bsearch(int x)		// 二分查找位于哪个区间左端点的右边
{
    int l = 0, r = vt.size() - 1;
    while(l < r)
	{
		int mid = l + r + 1 >> 1;
		if(check(mid, x))	l = mid;
		else	r = mid - 1;
	}
	return l;
}

void solve()
{
    vt.clear();
    int n, l, r, a, b, q, x;
    cin >> n;
    for(int i = 0; i < n; i ++)
    {
        cin >> l >> r >> a >> b;
        vt.push_back({l, b});
    }
    merge(vt);
    cin >> q;
    while(q --)
    {
        cin >> x;
        int p = bsearch(x);
        if(x >= vt[p].first && x <= vt[p].second)   x = vt[p].second;	// 若处于传送区间内则传送
        cout << x << " ";
    }
    cout << endl;
}



E Maximum Monogonosity

线段的成本定义为



b

l

a

r

+

b

r

a

l

|b_l-a_r|+|b_r-a_l|










b










l






























a










r























+












b










r






























a










l
























,求出总长度等于



k

k






k





且不相交的线段的最大成本总和

显然这是一个DP。参考洛谷题解:

CF1859E Maximum Monogonosity – 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

由于



a

b

=

m

a

x

(

a

b

,

b

a

)

|a-b|=max(a-b,b-a)









a













b







=








ma


x


(


a













b


,




b













a


)





,那么



b

l

a

r

+

b

r

a

l

=

m

a

x

(

b

l

a

r

,

a

r

b

l

)

+

m

a

x

(

b

r

a

l

,

a

l

b

r

)

|b_l-a_r|+|b_r-a_l|=max(b_l-a_r, a_r-b_l)+max(b_r-a_l,a_l-b_r)










b










l






























a










r























+












b










r






























a










l























=








ma


x


(



b










l






























a










r


















,





a










r






























b










l


















)




+








ma


x


(



b










r






























a










l


















,





a










l






























b










r


















)





,会出现四种组合方式。



dp[i][j]

表示前

i

个单位中选择长度为

j

的线段的最大价值。若第

i

个单位不选,那么由



d

p

[

i

1

]

[

j

]

dp[i-1][j]






d


p


[


i













1


]


[


j


]





转移过来。如果选择第

i

个单位,那么再考虑线段的长度,假设线段的长度为

k

,那么由

dp[i-k][j-k]+cost(i-k+1,i)

,并从

0~j

枚举k即可。因此



O

(

n

k

2

)

O(nk^2)






O


(


n



k










2









)





的转移方程为





d

p

i

,

j

=

m

a

x

(

d

p

i

1

,

j

,

m

a

x

k

=

1

j

(

d

p

i

k

,

j

k

+

a

i

b

i

k

+

1

+

b

i

a

i

k

+

1

)

)

dp_{i,j}=max(dp_{i-1,j},max_{k=1}^{j}(dp_{i-k,j-k}+|a_i-b_{i-k+1}|+|b_i-a_{i-k+1}|))






d



p











i


,


j





















=








ma


x


(


d



p











i





1


,


j



















,




ma



x











k


=


1










j



















(


d



p











i





k


,


j





k





















+












a










i






























b











i





k


+


1
























+












b










i






























a











i





k


+


1






















))







代入绝对值不等式,可以化简为





m

a

x

k

=

1

j

d

p

i

k

,

j

k

+

a

i

b

i

k

+

1

+

b

i

a

i

k

+

1

m

a

x

k

=

1

j

d

p

i

k

,

j

k

+

a

i

b

i

k

+

1

+

a

i

k

+

1

b

i

m

a

x

k

=

1

j

d

p

i

k

,

j

k

+

b

i

k

+

1

a

i

+

b

i

a

i

k

+

1

m

a

x

k

=

1

j

d

p

i

k

,

j

k

+

b

i

k

+

1

a

i

+

a

i

k

+

1

b

i

max_{k=1}^{j}dp_{i-k,j-k}+a_i-b_{i-k+1}+b_i-a_{i-k+1} \\ max_{k=1}^{j}dp_{i-k,j-k}+a_i-b_{i-k+1}+a_{i-k+1}-b_i \\ max_{k=1}^{j}dp_{i-k,j-k}+b_{i-k+1}-a_i+b_i-a_{i-k+1} \\ max_{k=1}^{j}dp_{i-k,j-k}+b_{i-k+1}-a_i+a_{i-k+1}-b_i \\






ma



x











k


=


1










j



















d



p











i





k


,


j





k





















+









a










i






























b











i





k


+


1





















+









b










i






























a











i





k


+


1

























ma



x











k


=


1










j



















d



p











i





k


,


j





k





















+









a










i






























b











i





k


+


1





















+









a











i





k


+


1































b










i
























ma



x











k


=


1










j



















d



p











i





k


,


j





k





















+









b











i





k


+


1































a










i




















+









b










i






























a











i





k


+


1

























ma



x











k


=


1










j



















d



p











i





k


,


j





k





















+









b











i





k


+


1































a










i




















+









a











i





k


+


1































b










i































(

m

a

x

k

=

1

j

d

p

i

k

,

j

k

a

i

k

+

1

b

i

k

+

1

)

+

a

i

+

b

i

(

m

a

x

k

=

1

j

d

p

i

k

,

j

k

+

a

i

k

+

1

b

i

k

+

1

)

+

a

i

b

i

(

m

a

x

k

=

1

j

d

p

i

k

,

j

k

a

i

k

+

1

+

b

i

k

+

1

)

a

i

+

b

i

(

m

a

x

k

=

1

j

d

p

i

k

,

j

k

+

a

i

k

+

1

+

b

i

k

+

1

)

a

i

b

i

(max_{k=1}^{j}dp_{i-k,j-k}-a_{i-k+1}-b_{i-k+1}) +a_i+b_i \\ (max_{k=1}^{j}dp_{i-k,j-k}+a_{i-k+1}-b_{i-k+1}) +a_i-b_i \\ (max_{k=1}^{j}dp_{i-k,j-k}-a_{i-k+1}+b_{i-k+1}) -a_i+b_i \\ (max_{k=1}^{j}dp_{i-k,j-k}+a_{i-k+1}+b_{i-k+1}) -a_i-b_i \\






(


ma



x











k


=


1










j



















d



p











i





k


,


j





k































a











i





k


+


1































b











i





k


+


1



















)




+









a










i




















+









b










i
























(


ma



x











k


=


1










j



















d



p











i





k


,


j





k





















+









a











i





k


+


1































b











i





k


+


1



















)




+









a










i






























b










i
























(


ma



x











k


=


1










j



















d



p











i





k


,


j





k































a











i





k


+


1





















+









b











i





k


+


1



















)














a










i




















+









b










i
























(


ma



x











k


=


1










j



















d



p











i





k


,


j





k





















+









a











i





k


+


1





















+









b











i





k


+


1



















)














a










i






























b










i

























定义

f[x][4]

为当前转移到的位置满足



i

j

=

x

i-j=x






i













j




=








x





时,上面四种情况的最大值分别是多少。复杂度为



O

(

n

k

)

O(nk)






O


(


nk


)





懵懵懂懂看懂了,等我再学一段时间动态规划再来补这个坑。

int n, k;
vector<ll> a(N), b(N);
ll dp[N][N], f[N][4];

void solve()
{
    memset(f, 0x80, sizeof f);	// 这里不是很懂为什么是0x80
    cin >> n >> k;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    for(int i = 1; i <= n; i ++) cin >> b[i];
    for(int i = 1; i <= n; i ++)
    {
        for(int j = 1; j <= k && j <= i; j ++)
        {
            dp[i][j] = dp[i - 1][j];
            f[i - j][0] = max(f[i - j][0], dp[i - 1][j - 1] + a[i] + b[i]);
			f[i - j][1] = max(f[i - j][1], dp[i - 1][j - 1] + a[i] - b[i]);
			f[i - j][2] = max(f[i - j][2], dp[i - 1][j - 1] - a[i] + b[i]);
			f[i - j][3] = max(f[i - j][3], dp[i - 1][j - 1] - a[i] - b[i]);
			dp[i][j] = max(dp[i][j], f[i - j][0] - a[i] - b[i]);
			dp[i][j] = max(dp[i][j], f[i - j][1] + a[i] - b[i]);
			dp[i][j] = max(dp[i][j], f[i - j][2] - a[i] + b[i]);
			dp[i][j] = max(dp[i][j], f[i - j][3] + a[i] + b[i]);
        }
    }
    cout << dp[n][k] << '\n';
}



版权声明:本文为m0_60541499原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。