hihocoder 第170周 Word Construction (dfs+剪枝)

本文介绍了一道编程题目,目标是在给定的英语常用词汇中找出最多数量的单词集合,这些单词之间没有共同的字母。文章提供了一个使用深度优先搜索(DFS)结合剪枝策略的解决方案,以高效地解决问题。

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

#1334 : Word Construction

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

Given N words from the top 100 common words in English (see below for reference), select as many words as possible as long as no two words share common letters.

Assume that the top 100 common words in English are:

the be to of and a in that have i it for not on with he as you do at this but his by from they we say her she or an will my one all would there their what so up out if about who get which go me when make can like time no just him know take people into year your good some could them see other than then now look only come its over think also back after use two how our work first well even new want because any these give day most us

输入

The first line contains an integer N, denoting the number of words. (1 ≤ N ≤ 40)  

The second line contains N words from the top 100 common words.

输出

Output the most number of words can be selected.

样例输入 8 the be to of and a in that  样例输出 4

题意:

给出N个单词(1 ≤ N ≤ 40),在满足各个单词之间没有重复字母的情况下,求能选取最多多少个单词。

题解:

dfs+剪枝,因为要求字母不重复

 

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 40 + 10;
int a[200] = {0}, vis[N] = {0};
string s[N];
int ans = 0, n;
int dfs(int num)
{
    int tmp = 0;
    vis[num] = 1;
    for(int i = 0; i < n; i++) {
        if(vis[i])
            continue;
        int len = s[i].length();
        //出现重复字母
        for(int j = 0; j < len; j++) {
            if(a[s[i][j]])
                len = -1;
        }
        if(len == -1)
            continue;
        for(int j = 0; j < len; j++) {
            a[s[i][j]]++;
        }
        tmp = max(tmp, dfs(i));
        for(int j = 0; j < len; j++) {
            a[s[i][j]]--;
        }
    }
    vis[num] = 0;
    return tmp + 1;
}
int  main()
{
    cin >> n;
    for(int i = 0; i < n; i++) {
        cin >> s[i];
    }
    int ans = 0;
    for(int i = 0; i < n; i++) {
        memset(vis, 0, sizeof(vis));
        memset(a, 0, sizeof(a));
        for(int j = 0; j < s[i].length(); j++)
            a[s[i][j]]++;
        ans = max(ans, dfs(i));
    }
    printf("%d\n", ans);
    return 0;
}

 

转载于:https://www.cnblogs.com/yu0111/p/7635747.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值