入门者笔记·CF游记

Clear the String

题目链接

Discription
You are given a string s of length n consisting of lowercase Latin letters. You may apply some operations to this string: in one operation you can delete some contiguous substring of this string, if all letters in the substring you delete are equal. For example, after deleting substring bbbb from string abbbbaccdd we get the string aaccdd.

Calculate the minimum number of operations to delete the whole string s.

Input
The first line contains one integer n (1≤n≤500) — the length of string ss.

The second line contains the string s (|s|=n) consisting of lowercase Latin letters.

Output
Output a single integer — the minimal number of operation to delete string s.

Examples
input
5
abaca
output
3
input
8
abcddcba
output
4
代码:

#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,dp[550][550];//dp[l][r]代表解决第l到r需要多少步
char ch[550];
int main()
{
	int i,l,j,r;
	scanf("%d",&n);
	scanf("%s",ch+1);
	for(i=1;i<=n;i++) dp[i][i]=1;
	for(i=2;i<=n;i++)
	{
		for(l=1;l<=n-i+1;l++)
		{
			r=l+i-1;
			dp[l][r]=1e9;
			dp[l][r]=min(dp[l][r],dp[l][r-1]+(ch[r-1]!=ch[r]));
			dp[l][r]=min(dp[l][r],dp[l][r-1]+(ch[r]!=ch[l]));
			dp[l][r]=min(dp[l][r],dp[l+1][r]+(ch[l]!=ch[l+1]));
			dp[l][r]=min(dp[l][r],dp[l+1][r]+(ch[l]!=ch[r]));//转移方程
			for(j=l;j<=r-1;j++)
				dp[l][r]=min(dp[l][r],dp[l][j]+dp[j+1][r]);//如果没有,会死在第五个点
		}
	}
	printf("%d\n",dp[1][n]);
	return 0;
}

Circus

题目链接

Discription
Polycarp is a head of a circus troupe. There are n — an even number — artists in the troupe. It is known whether the i-th artist can perform as a clown (if yes, then ci=1, otherwise ci=0), and whether they can perform as an acrobat (if yes, then ai=1, otherwise ai=0).

Split the artists into two performances in such a way that:

each artist plays in exactly one performance,
the number of artists in the two performances is equal (i.e. equal to n2),
the number of artists that can perform as clowns in the first performance is the same as the number of artists that can perform as acrobats in the second performance.
Input
The first line contains a single integer n (2≤n≤5000, n is even) — the number of artists in the troupe.

The second line contains n digits c1c2…cn, the i-th of which is equal to 1 if the i-th artist can perform as a clown, and 0 otherwise.

The third line contains n digits a1a2…an, the i-th of which is equal to 1, if the i-th artist can perform as an acrobat, and 0 otherwise.

Output
Print n2 distinct integers — the indices of the artists that should play in the first performance.

If there are multiple answers, print any.

If there is no solution, print a single integer −1.

Examples
input
4
0011
0101
output
1 4
input
6
000000
111111
output
-1
input
4
0011
1100
output
4 3
input
8
00100101
01111100
output
1 2 3 6
Note
In the first example, one of the possible divisions into two performances is as follows: in the first performance artists 1 and 4 should take part. Then the number of artists in the first performance who can perform as clowns is equal to 1. And the number of artists in the second performance who can perform as acrobats is 1 as well.

In the second example, the division is not possible.

In the third example, one of the possible divisions is as follows: in the first performance artists 3 and 4 should take part. Then in the first performance there are 2 artists who can perform as clowns. And the number of artists in the second performance who can perform as acrobats is 2 as well.

代码:
由此题数据规模可以看出,使用暴力枚举为此题正解。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
int n,a,b,c,d,a1,b1,c1,d1;
int qq[5050],ww[5050];
char ch1[5050],ch2[5050];
vector<int>aa;//aa代表都不会
vector<int>bb;//bb代表只会第一个
vector<int>cc;//cc代表只会第二个
vector<int>dd;//dd代表都会
int main()
{
	int i,j,t,q;
	a=b=c=d=0;
	scanf("%d",&n);
	scanf("%s",ch1);
	scanf("%s",ch2);
	for(i=1;i<=n;i++)
	{
		qq[i]=ch1[i-1]-'0';
		ww[i]=ch2[i-1]-'0';
	}
	for(i=1;i<=n;i++)
	{
		if(qq[i]&&ww[i])
	    {d++;dd.push_back(i);}
		else if(qq[i]&&!ww[i]) 
		{b++;bb.push_back(i);}
		else if(ww[i]&&!qq[i])
		{c++;cc.push_back(i);}
		else
		{a++;aa.push_back(i);}
	}
	for(i=0;i<=d;i++)//暴力枚举在第一场演出中dd的数量
	{
		for(j=0;j<=b;j++)//枚举bb的数量
		{
			t=c-j+d-i-i;
			q=min(n/2-i-j,c);
			if(t>=0&&t<=q)
			{
				if(a<n/2-t-i-j) continue;
				for(a1=0;a1<n/2-t-i-j;a1++) printf("%d ",aa[a1]);
				for(b1=0;b1<j;b1++) printf("%d ",bb[b1]);
				for(c1=0;c1<t;c1++) printf("%d ",cc[c1]);
				for(d1=0;d1<i;d1++) printf("%d ",dd[d1]);
				printf("\n");
				return 0;		
			}
		}
	}
	printf("-1\n");
	return 0;
}

与上一题相比,可以总结一个并不可以推广的规律:数据范围小于500时,可以尝试三重循环,小于5000时,可以试试二重循环。

猜你喜欢

转载自blog.csdn.net/weixin_43918350/article/details/88564256