2022ICPC网络赛第二场

B

题意:
就是给你一个n(n<=100)的数组,这个数组是非下降的,然后定义这个数组的价值是所有(va[i]-va[i-1])2 。然后每次操作,你可以选择一个数删掉或者不删,然后再让其中一个数变成任意其他的数。但是不能操作第一个数和最后一个数。现在让你输出操作次数分别为[1,n]的答案。

思考:

  1. 当时看到这题,看到数组范围很小,感觉有点像区间dp,但是又有一个操作次数的限制,区间dp的话这都4维了,所以并不是。然后我又想感觉是思维?但是想了几个贪心并不对。然后就有点无语了,然后感觉周从开始都在看这个,应该可以写出来,但是也是卡住了。
  2. 其实这题,没更深入的思考,注意看要么是删去,要么是变成任意数,但是又不能动最两端的数,那么可以发现对于删掉和变成任意的数,这两种操作产生的贡献是一样的,因为删掉和变数都是产生左边和右边乘积的贡献。
  3. 所以这样就简单了,求最大值最小值,往往就是贪心,二分,dp。转化后发现贪心也不太好贪心,二分也不好处理,那么就dp。可以定义dp状态为dp[i][j]为第i个选择,并且用了j次操作的最大值。那么就可以三重循环去更新dp了。对于最后输出n个答案,就看看用了2×i次操作可以达到什么答案,由于操作n-2次就是最大值了,那么就是dp[n][min(i*2,n-2)]。由于转移的时候,至少是从1来转移的,所以1是必选的,而且dp[n]也是n必选的,所以就保证了答案的正确性。
  4. 说真的,比赛的时候,就要像平时做题一样,仔细思考,有时间去解决。对于任意一个题目,都不能把那种想把题目交给的队友的思想。因为有时候不同的思想对题目的解决很重要,有时候队友的思路被卡,就需要自己去解决。对于一个题目想不同的算法的时候,都要深入思考一下,真的是不是没有办法解决,而不是感觉没有就直接换算法。

代码:

#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define db double
#define int long long
#define PII pair<int,int >
#define mem(a,b) memset(a,b,sizeof(a))
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);

using namespace std;
const int mod = 1e9+7,inf = 1e18;
const int N = 2e5+10,M = 2010;

int T,n,m,k;
int va[N];
int dp[M][M];

signed main()
{
	IOS;
	cin>>n;
	for(int i=1;i<=n;i++) cin>>va[i];
	for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dp[i][j] = -inf;
	int sum = 0;
	for(int i=2;i<=n;i++) //这个初始化加不加都可,但是最好还是养成初始化的好习惯
	{
		sum += (va[i]-va[i-1])*(va[i]-va[i-1]);
		dp[i][0] = sum;
	}
	for(int i=2;i<=n;i++)
	{
		for(int j=0;j<=n-2;j++)
		{
			for(int k=1;k<i;k++)
			{
				int res = i-k-1;
				if(j>=res)
				dp[i][j] = max(dp[i][j],dp[k][j-res]+(va[i]-va[k])*(va[i]-va[k]));
			}
		}
	}
	for(int i=1;i<=n;i++) cout<<dp[n][min(i*2,n-2)]<<"\n";
	return 0;
}

J

题意:

思考:

代码:

#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define db double
#define int long long
#define PII pair<int,int >
#define mem(a,b) memset(a,b,sizeof(a))
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);

using namespace std;
const int mod = 1e9+7,inf = 1e18;
const int N = 2e5+10,M = 2010;

int T,n,m,k;
int va[N];

signed main()
{
	IOS;
	cin>>n;
	for(int i=1;i<=n;i++) cin>>va[i];
	int t1 = 0,t2 = 0;
	for(int i=1;i<=n;i++)
	{
		if(va[i]>va[i-1]) t1++;
		else break;
	}
	for(int i=n;i>=1;i--)
	{
		if(va[i]>va[i+1]) t2++;
		else break;
	}
	if(t1%2!=0||t2%2!=0) cout<<"Alice";
	else cout<<"Bob";
	return 0;
}

F

题意:

思考:

代码:

A

题意:

思考:

代码:

G

题意:

思考:

代码:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值