4304. 字符串归类

给定 n 个由小写字母构成的字符串。

现在,请你对它们进行归类。

对于两个字符串 a 和 b:

如果至少存在一个字母在 a 和 b 中同时出现,则 a 和 b 属于同一类字符串。
如果字符串 c 既与字符串 a 同类,又与字符串 b 同类,则 a 和 b 属于同一类字符串。
请问,最终所有字符串被划分为多少类。

输入格式
第一行包含整数 n。

接下来 n 行,每行包含一个仅由小写字母构成的字符串。

注意,输入字符串可能相同。

输出格式
一个整数,表示最终所有字符串被划分为的类的数量。

数据范围
前 6 个测试点满足 1≤n≤10。
所有测试点满足 1≤n≤2×105,输入字符串的长度范围 [1,50],所有输入字符串的总长度范围 [1,106],所有字符串均由小写英文字母构成。

输入样例1:
4
a
b
ab
d
输出样例1:
2
输入样例2:
3
ab
bc
abc
输出样例2:
1
输入样例3:
1
abcdefghijklmn
输出样例3:
1


#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

const int N = 110;

int n, m;
int v[N][N], w[N][N]; // v[i][j] 表示第i组第j个物品
int s[N];

int f[N][N]; // f[i][j] 表示前i组物品,容量为j的情况下的最大值

int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++)
    {
        
        scanf("%d", &s[i]);
        
        for(int j = 1; j <= s[i]; j++)
        {
            scanf("%d%d", &v[i][j], &w[i][j]);
        }
    }
    
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
        {
            f[i][j] = f[i-1][j]; // 不选第i组的物品
            for(int k = 1; k <= s[i]; k++)
            {
                if(j >= v[i][k]) f[i][j] = max(f[i][j], f[i-1][j-v[i][k]] + w[i][k]);
            }
        }
    cout << f[n][m];
    return 0;
    
}

posted @ 2022-02-23 23:02  VanHope  阅读(45)  评论(0编辑  收藏  举报