Codeforces Round #267 (Div. 2) 解题报告

N久没做过cf了,今天心血来潮搞了一个,唉,坑爹的D题,卡了N久

解题:

A题George and Accommodation

直接暴力


B题Fedor and New Game

也是直接暴力


C题George and Jo

题目:

给定一个序列,给定一个块的大小m(必须为连续),给定k个块(不能交叉,只能顺序),求k块之和最大是多少。

简单DP,状态转移方程:

f[i][j] = max(f[i - 1][j], f[i - m][j - 1] + sum[i - m]);

其中i表示遍历原数组到i为止,j表示第j组(一共k组),sum[i - m]表示以i - m为开头的连续的块和

代码:

#include<iostream>
#include<cstdio>
#include<memory.h>
#include<queue>
#include<cmath>
#include<stack>
#include<cstdlib>
#include<vector>
#include<string>
#include<cstring>
#include<map>

using namespace std;
#define Clear(f, nr) memset(f, nr, sizeof(f))
const int SIZE = 5005;
const int MSIZE = 10000;
typedef long long ll;
const int INF = 1 << 30;

long long f[SIZE][SIZE];
long long sum[SIZE];
int a[SIZE];

int main() {
	int n, m, k;
	while(cin >> n >> m >> k) {
		for(int i = 0; i < n; i ++)
			cin >> a[i];
		Clear(sum, 0);
		for(int i = 0; i < m; i ++)
			sum[0] += a[i];
		for(int i = 1; i < n - m + 1; i ++)
			sum[i] = sum[i - 1] - a[i - 1] + a[i + m - 1];
		for(int i = 0; i < n; i ++)
			f[i][0] = 0;
		f[m - 1][1] = sum[0];
		for(int i = m; i < n; i ++) {
			for(int j = 1; j <= k; j ++)
				f[i][j] = max(f[i - 1][j], f[i - m][j - 1] + sum[i - m + 1]);
		}
		cout << f[n - 1][k] << endl;
	}
}


D题 Fedor and Essay

给定一个字符串序列,求替换其中的字符串使得替换后的数据含单词r最少(忽略大小写),如果r一致,则输出长度最小的。

解题:

暴力搞得,一开始卡第六组数据,后来发现可以循环替换a->b->c....一直替换下去

结果还是卡第七组数据。。。。

我的思路就是替换 如果想要替换a为b

则b中要么r比a少,要么b字符串比a短。

后来发现思路是错的,根据第7组数据:

5
aa bb cc ee ff
5
aa a
bb aa
cc bb
ee cc
ff bb
按我的思路替换是不对的。

因为数据替换张成了一棵树,需要dfs遍历找到替换最优解(根据以上的替换规则,必为叶子结点)
完了dfs时再把中间压缩一下,中间节点直接map到最优叶子节点

由于中间过程存在环,还要强连通缩点,重构图。

代码写的太乱了,不发了。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值