NEERC 2014, Eastern subregional contest 题解

本文介绍了NEERC 2014东方子区域竞赛中的一道题目,内容涉及如何构造一个长度为n的01序列,其中连续0的最大数目不超过a,连续1的最大数目不超过b。通过动态规划方法(dp[i][j][0]和dp[i][j][1]分别表示前i个数中以j个0和1结尾的方法数)求解该问题,并提到第一维需要使用滚动数组进行优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <cstdio>
int main() {
	int n;
	while(~scanf("%d", &n)) {
		if(n >= 7) puts("YES");
		else puts("NO");
	}
	return 0;
}
题解: 点击打开链接

题解: 点击打开链接


看清题意就好。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int N = 500;
int money, alone, with;
int n, m;
struct node{
    int mon, adv;
}fri[N];
struct room{
    int bed, cost, adv;
}ap[N];
void input(){
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)scanf("%d %d", &fri[i].mon, &fri[i].adv);
    scanf("%d", &m);
    for(int i = 1; i <= m; i++)scanf("%d %d %d", &ap[i].bed, &ap[i].cost, &ap[i].adv);
}

int main(){
	while (~scanf("%d %d %d", &money, &alone, &with)){
        input();
        int adv = -1;
        bool afford = false;
        int self = 0, peo = 0, peo_room = 0;
        for(int i = 1; i <= m; i++)
            if(money >= ap[i].cost)
            {
                afford = true;
                int tmp;
                if(ap[i].bed == 1) tmp = alone;
                else tmp = with;
                if(adv < ap[i].adv+tmp)
                {
                    adv = ap[i].adv+tmp;
                    self = i;
                }
            }
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++)
            if(ap[j].bed >= 2 && ap[j].cost<=money*2 && ap[j].cost<=fri[i].mon*2)
            {
                afford = true;
                if(adv < ap[j].adv+fri[i].adv)
                {
                    self = 0;
                    peo = i; peo_room = j;
                    adv = ap[j].adv+fri[i].adv;
                }
            }
        if(false == afford)
            puts("Forget about apartments. Live in the dormitory.");
        else if(self)
            printf("You should rent the apartment #%d alone.\n", self);
        else
            printf("You should rent the apartment #%d with the friend #%d.\n", peo_room, peo);
	}
	return 0;
}
题解: 点击打开链接


题意:构造一个01序列使得长度为n,连续0的个数<=a, 连续1的个数<=b

问:方法数

dp[i][j][0] 表示前i个数中结尾连续j个0 的方法数

dp[i][j][1]表示前i个数中结尾连续j个1的方法数。

==然后第一维要用滚动数组优化一下。。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int N = 50100;
void add(ll &u, ll v){
    u += v;
    if(u>=mod) u -= mod;
}
int a, b, n;
ll dp[2][305][2];
int main(){
	while (~scanf("%d %d %d", &n, &a, &b)){
        memset(dp, 0, sizeof dp);
        int now = 0, oth = 1;
        dp[now][1][0] = dp[now][1][1] = 1;

        for(int i = 2; i <= n; i++)
        {
            memset(dp[oth], 0, sizeof dp[oth]);
            for(int j = 1; j <= min(a, i); j++)
                if(dp[now][j][0])
                {
                    if(j+1<=a)
                    add(dp[oth][j+1][0], dp[now][j][0]);
                    add(dp[oth][1][1], dp[now][j][0]);
                }
            for(int j = 1; j <= min(b, i); j++)
                if(dp[now][j][1])
                {
                    if(j+1<=b)
                        add(dp[oth][j+1][1], dp[now][j][1]);
                    add(dp[oth][1][0], dp[now][j][1]);
                }
                now ^= 1;
                oth ^= 1;
        }
        ll ans = 0;
        for(int i = 1; i <= a; i++)
            add(ans, dp[now][i][0]);
        for(int i = 1; i <= b; i++)
            add(ans, dp[now][i][1]);
        cout<<ans%mod<<endl;
	}
	return 0;
}

#include <cstdio>
#include <cstring>
#include <cmath>
#include <stack>
using namespace std;
const int N = 5005;
char s[N*2];
int ans[N];
struct node {
	int id;
	char ch;
};
stack< node > a;

int main() {
	int n;
	while (~scanf("%d", &n)) {
		scanf("%s", s);
		while(a.size()) a.pop();
		int ida=0, idb=0;
		for(int i = 0; i < 2*n; i ++) {
			node tmp;
			tmp.ch = s[i];
			if(s[i] >= 'a' && s[i] <= 'z') {
				tmp.id = ida++;
			} else if(s[i] >= 'A' && s[i] <= 'Z') {
				tmp.id = idb++;
			}
			if(a.size()) {
				node t = a.top();
				if( t.ch == tmp.ch + 32) {
					ans[ tmp.id] = t.id;
					a.pop();
				} else if( t.ch + 32 == tmp.ch) {
					ans[ t.id] = tmp.id;
					a.pop();
				} else
					a.push(tmp);

			} else a.push(tmp);
		}
		if(a.size()) {
			puts("Impossible");
		} else {
			for(int i = 0; i < n; i ++) {
				if(i != 0) putchar(' ');
				printf("%d", ans[i]+1);
			} puts("");
		}
	}
	return 0;
}


#include <cstdio>
#include <cstring>
const int N = 1005;
char a[N], b[N];
int main() {
	while(~scanf("%s%s", a, b)) {
		int len1 = strlen(a);
		int len2 = strlen(b);
		int i = 0, j = 0, ans = 0;
		while(i < len1 && j < len2) {
			if(a[i] == 'L' && (b[j] == 'F' || b[j] == 'R')) {
				j ++;
				ans ++;
			} else if((a[i] == 'F'||a[i] == 'R') && b[j] == 'L') {
				i ++;
				ans ++;
			} else {
				i ++;
				j ++;
				ans ++;
			}
		}
		ans += len1-i + len2-j;
		printf("%d\n", ans);
	}
	return 0;
}

#include <cstdio>
#include <cstring>
#include <map>
#include <string>
#include <iostream>
#include <cmath>
#include <vector>

using namespace std;

const int MAX_N = 1007;

int n;
int a[MAX_N], b[MAX_N];
int p1[7], p2[7];
vector<int> v1[7], v2[7];
vector<int> ans1, ans2;

void Clear() {
	for (int i = 0; i < 7; ++i) v1[i].clear(), v2[i].clear();
	ans1.clear(), ans2.clear();
}

int main() {
	while (1 == scanf("%d", &n)) {
		Clear();
		int sa=0, sb=0;
		for (int i = 1; i <= n; ++i) {
			scanf("%d", &a[i]);
			v1[a[i]].push_back(i);
			sa+=a[i];
		}
		for (int i = 1; i <= n; ++i) {
			scanf("%d", &b[i]);
			v2[b[i]].push_back(i);
			sb+=b[i];
		}
		for (int i = 0; i <= 6; ++i) {
			p1[i] = 0, p2[i] = 0;
			int len1 = v1[i].size(), len2 = v2[i].size();
			while (p1[i] < len1 && p2[i] < len2) {
				ans1.push_back(v1[i][p1[i]]), ans2.push_back(v2[i][p2[i]]);
				++p1[i], ++p2[i];
			}
		}
		if(sa > sb) {
			for (int i = 0; i <= 6; ++i) {
				for (int j = p1[i]; j < v1[i].size(); ++j) {
					ans1.push_back(v1[i][j]);
				}
			}
			for (int i = 6; i >= 0; --i) {
				for (int j = p2[i]; j < v2[i].size(); ++j) {
					ans2.push_back(v2[i][j]);
				}
			}
		} else {
			for (int i = 6; i >= 0; --i) {
				for (int j = p1[i]; j < v1[i].size(); ++j) {
					ans1.push_back(v1[i][j]);
				}
			}
			for (int i = 0; i <= 6; ++i) {
				for (int j = p2[i]; j < v2[i].size(); ++j) {
					ans2.push_back(v2[i][j]);
				}
			}
		}
		for (int i = 0; i < n; ++i) printf("%d %d\n", ans1[i], ans2[i]);
	}
	return 0;
}


#include <cstdio>
#include <cstring>
#include <map>
#include <string>
#include <iostream>
#include <cmath>

using namespace std;

int n;

int main() {
	map<string,int> mp;
	mp["Alice"] = mp["Ariel"] = mp["Aurora"] = 
	mp["Phil"] = mp["Peter"] = mp["Olaf"] = 
	mp["Phoebus"] = mp["Ralph"] = mp["Robin"] = 0;
	mp["Bambi"] = mp["Belle"] = mp["Bolt"] = 
	mp["Mulan"] = mp["Mowgli"] = mp["Mickey"] = 
	mp["Silver"] = mp["Simba"] = mp["Stitch"] = 1;
	mp["Dumbo"] = mp["Genie"] = mp["Jiminy"] = 
	mp["Kuzko"] = mp["Kida"] = mp["Kenai"] = 
	mp["Tarzan"] = mp["Tiana"] = mp["Winnie"] = 2;
	while (1 == scanf("%d", &n)) {
		string str;
		int ans = 0, pos = 0;
		for (int i = 0; i < n; ++i) {
			cin >> str;
			ans += abs(mp[str] - pos);
			pos = mp[str];
		}
		printf("%d\n", ans);
	}
	return 0;
}




















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值