2016 World Final K String Theory

题意:

递归定义了k-quotation是k个分号+若干个(k-1)-quotataion+k个分号,然后给你很多个分号,叫你求一下最大是多少quotation。

思路:

对于一个k-quotation,分号的前缀形式肯定是(k)(k-1)(k-2)..(1)(1),然后后面可以考虑继续接(1)(1)或者接一个(2)。因此,可以先枚举quotation为k,从后往前dp。dp[i][j][t] 表示考虑a[i]第j个以及后面的分号,它的前面是有一个(t - 1)的分号,能不能构成满足条件的分法。有两种转移,一种是再接一个(t-1)-quotation,也就是(t-1)(t-2)...(1)(1),或者是结束这个(t-1)-quotation,加上一个(t)。

#include <bits/stdc++.h>

using namespace std;

#define LL long long
#define pii pair<int, int>
#define MP make_pair
#define inf 0x3f3f3f3f
#define mod 1000000007
#define eps 1e-12
#define Pi acos(-1.0)
#define N 110
#define M 200020
#define PB push_back
#define MP make_pair
#define fi first
#define se second

bool dp[N][N][N];
pii f[N][N][N];

int n, a[N];

pii calc(int x, int y, int t) {
	pii ret(-1, -1);
	for(int i = t; i >= 1; --i) {
		if(y + i - 1 > a[x]) return ret;
		y += i;
		if(y > a[x]) x++, y = 1;
		if(x > n) return ret;
	}
	y++;
	if(y > a[x]) x++, y = 1;
	return MP(x, y);
}

pii jump(int x, int y, int t) {
	if(y + t - 1 > a[x]) return MP(-1, -1);
	y += t;
	if(y > a[x]) x++, y = 1;
	return MP(x, y);
}
int main() {
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i) {
		scanf("%d", &a[i]);
	}
	for(int i = 1; i <= n; ++i) {
		for(int j = 1; j <= a[i]; ++j) {
			for(int t = 1; t <= 100; ++t) {
				f[i][j][t] = calc(i, j, t);
			}
		}
	}
	int ans = 0;
	for(int k = 1; k <= 100; ++k) {
		if(f[1][1][k].fi == -1) continue;
		memset(dp[n + 1][1], 0, sizeof dp[n + 1][1]);
		dp[n + 1][1][k] = 1;
		int dx = f[1][1][k].fi;
		int dy = f[1][1][k].se;
		for(int i = n; i >= dx; --i) {
			for(int j = a[i]; j >= 1; --j) {
				for(int t = k - 1; t >= 1; --t) {
					pii p = jump(i, j, t + 1);
					dp[i][j][t] = 0;
					if(p.fi != -1) {
						dp[i][j][t] |= dp[p.fi][p.se][t + 1];
					}
					if(f[i][j][t].fi != -1) {
						int xx = f[i][j][t].fi;
						int yy = f[i][j][t].se;
						dp[i][j][t] |= dp[xx][yy][1];
					}
				}
			}
		}
		if(dp[dx][dy][1]) ans = max(ans, k);
	}
	if(ans == 0) puts("no quotation");
	else printf("%d\n", ans);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值