CF Educational Codeforces Round 61 (Rated for Div. 2)

A 题
水题不解释,主要是用vector容器就行了,不然开数组还稍微麻烦一点。

#include<iostream>
#include<string>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
typedef pair<int, int> pir;
struct ss {
	int ab, sc;
}p[200];
int main()
{
	int n, m, k;
	cin >> n >> m >> k;
	vector<int >v[105];
	up(i, 0, n)
	{
		cin >> p[i].ab;
	}
	up(i, 0, n)
	{
		cin >> p[i].sc;
		v[p[i].sc].push_back(p[i].ab);
	}
	up(i, 0, n)
	{
		sort(v[i].begin(), v[i].end(),greater<int >());
	}
	int kk[105];
	int ans = 0;
	up(i, 0, k)
	{
		cin >> kk[i];
		if (v[p[kk[i]-1].sc].front() != p[kk[i]-1].ab)
			ans++;
	}
	cout << ans;
	return 0;
}

B题 代码略 写的很丑。。
主要就是暴力求解两两的和。题目告诉我们糖果数量unique,那么如果出现两个9,必然就是不同的四个数字组成的,所以开数组储存所有
两两的和,然后upper-lower_bound就得到答案。(其实感觉二分查答案应该算很快的方法了把)


c题水题,模拟题目。
代码略。。也是写的很丑。
主要在于这里数据给的小,所以我直接暴力for(i,0,t)t就是时间。
然后对于每一个时间,让在队伍里面的test++,知道有一个== ai了,出队,然后让下一个入队。
在每一个时刻还需要做的事情,如果有一个test==d了,那么ans++。最后ans就是答案。



F题,求子串的代价。``
代码很简单,但是思想还是重要的。
这道理类似于白皮书上,用线段树来维护dp得题目。
对于每一个区间,找端点值在(l,r)种中的,然后更新dp。
这道题目类似,但是是关于字符串的,也是关于前缀的一道题。
我们思考可以得出状态转移方程
dp[i]=min(dp[i]+a,dp[L]+b|i-R>L)
也就是说,dp能从,以i结尾的某个前缀的前一个字母+b转移过来。
所以我们首先预处理前缀,对于任意的i,从0-i来寻找,找si==sj,然后开个二维数组来保存任意j,i的前缀长度就好了。

#include<iostream>
#include<string>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
typedef pair<int, int> pir;
string s;
int cnt[5500][5500];
int dp[5500];
int main()
{
	int n, a, b;
	cin >> n >> a >> b;
	cin >> s;
	up(i, 1, n)
	{
		up(j, 0, i)
		{
			if (s[i] == s[j])
			{
				cnt[i][j] = 1;
				if (j)cnt[i][j] += cnt[i - 1][j - 1];
			}
		}
	}//预处理前缀,以前一直以为这样暴力是解决不了的。。今天终于有用处了
	dp[0] = a;
	up(i, 0, n)
	{
		if (i)dp[i] = dp[i - 1] + a;
		up(j, 0, i)
		{
			if (cnt[i][j])
			{
				if (i - cnt[i][j] + 1 > j)//注意!例如aaa这样的,可能重叠
				{
					dp[i] = min(dp[i], dp[i - cnt[i][j]] + b);
				}//状态转移方程
			}
		}
	}
	cout << dp[n - 1] << endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44019404/article/details/89249258