Dance Recital

The Production Manager of a dance company has been tasked with determining the cost for the seasonal
dance recital. Because of their exceptional skills, many dancers will perform in more than one routine,
but this presents a problem; each dance routine incorporates a unique costume, so between routines,
dancers must report backstage to a Wardrobe Specialist, who can change the dancer’s costume in time
to begin their next scheduled routine.
A Wardrobe Specialist does a normal change on a dancer when the dancer performs in two routines
that are not consecutive, but when a dancer is required to perform in two consecutive routines, a quick
change is necessary. A Wardrobe Specialist charges a flat rate per recital that covers all normal changes,
but charges an exorbitant amount for each quick change. The Production Manager is responsible for
keeping the show under budget, and has hired you to write a program to report the minimum number
of quick changes needed for a given recital, given that the order of the dance routines could be changed.
To describe the cast of dancers that are to perform during a recital, each dancer is assigned an
identifying uppercase letter. (Fortunately, there are never more than 26 dancers, so characters from A
to Z suffice.) To describe a full recital, a list of individual routines is given, with a string of characters
defining which dancers appear in a routine. For example, consider the following recital description:
ABC
ABEF
DEF
ABCDE
FGH
The above list describes a recital with 5 dance routines, including a total of 8 individual performers
(dancers A through H). The first routine listed includes dancers {A, B, and C}. The second routine
includes dancers {A, B, E, and F}. Notice that if these first two routines are performed in the above
order, dancers A and B will require a quick change between the routines. In fact, if these five routines
are scheduled in the order given above, a total of six quick changes are required. However, the schedule
can be rearranged as follows:
ABEF
DEF
ABC
FGH
ABCDE
In this case, only two quick changes are required (those for E and F between the first two dances).
Input
The input file contains several test cases, each of them as described below.
The first line contains a single integer R, with 2 ≤ R ≤ 10, that indicates the number of routines
in the recital. Following that will be R additional lines, each describing the dancers for one routine in
the form of a nonempty string of up to 26 non-repeating, lexicographically sorted uppercase alphabetic
characters identifying the dancers who perform in that routine. Although a dancer’s letter will not
appear more than once in a single routine, that dancer may appear in many different routines, and it
may be that two or more routines have the identical set of dancers.
ACM-ICPC Live Archive: 7352 – Dance Recital 2/2
Output
For each test case, output a single integer designating the minimum number of quick changes required
for the recital on a line by itself.
Sample Input
5
ABC
ABEF
DEF
ABCDE
FGH
6
BDE
FGH
DEF
ABC
BDE
ABEF
4
XYZ
XYZ
ABYZ
Z
Sample Output
2
3
4
题意:找出最小相邻字符串的相同字符之和。
对a进行全排列,按字典序排列。
标准库中next_permutation函数:找当前序列中元素排列的下一个排列,按照字典顺序进行排列。比如说数组排列"123",那么它的下一个排列为"132",并且返回true。如果当前序列没有下一个排列,我们返回false,且把当前排列置为最小的排列,比如说:排列"321",因为该排列已经是最大的排列,所以它没有下一个排列。我们把该排列置为"123",并且返回false。

#include<algorithm>
next_permutation(a , a + n )
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <set>
#include <map>
#define PI acos(-1)
const int mod = 1000000009;
const int maxx = 1e9;
typedef long long LL;
using namespace std;
int main()
{
    int n;
    int pos[20];//记录字符串位置,进行权排列.
    int len[20];//记录字符串长度
    int ans[20][50];
    char s[20][50];
    while(cin>>n)
    {
        for(int i=1; i<=n; i++)
        {
            cin>>s[i];
            pos[i]=i;
            len[i]=strlen(s[i]);
        }
        memset(ans,-1,sizeof(ans));
        int sum = maxx;
        do
        {
            int sum1 = 0;
            int p1,p2;
            for(int i=1; i<n; i++)
            {
                p1=pos[i],p2=pos[i+1];
                //if条件可以节省时间,如果上一次算过这两个字符串的全排列直接向加
                if(ans[p1][p2] > -1)
                {
                    sum1 += ans[p1][p2];
                    continue;
                }
                int ant=0;
                for(int i=0; i<len[p1]; i++)
                {
                    for(int j=0; j<len[p2]; j++)
                    {
                        if(s[p1][i]==s[p2][j])
                        {
                            ant++;
                            break;
                        }
                    }
                }
                ans[p1][p2]=ant;
                sum1+=ant;
            }
            sum = min(sum1,sum);
        }while(next_permutation(pos+1,pos+1+n));
        cout<<sum<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值