uva1377 ruler

本文探讨了在给定一系列长度的基础上,设计一个尺子以最小化所需刻度数并保持尺子长度最小的方法。通过广度优先搜索算法,实现了解决方案,并在判重时采用了一种高效策略,确保了算法的正确性和效率。

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

Ruler 

给你一系列的长度。你要制作一个有m个刻度的尺子,使得任意一个长度都能以某两个刻度之间的距离表示

要求m尽量小的前提下尺子长度尽量小。你可以认为刻度数不超过7

首先要想明白的一点,尺子长度就为这n个长度中的最大值。以这个值为长度的尺子一定能满足m尽量小。

然后我们如何去搜索呢?我们的刻度是任意的,但可以跟给定长度建立关系。我们枚举一个当前还不能表示的长度,然后枚举这个长度是由哪个已有刻度和新刻度共同产生的。这样的做法是显然能得到解的。还有一个重要问题,如何判重呢?我们只要判断当前状态能表示哪些刻度就有了——即表示的给定长度都相同的两种状态视为同一种状态。其中的原因可以这么想。因为枚举刻度的时候我们确定了左端点和右端点,即0和尺子的最大刻度。

然后这样对广搜判重的时候就有两种情况

1.当前得到的状态消耗刻度数比相同状态的所用刻度数多

这种情况不必多说,说明当前的刻度划分方式是不明智的一种,显然应该舍弃之。

2.当前得到的状态消耗刻度数和相同状态的所有刻度数一样多

因为左右端点确定,若他们表示的状态都相同,要么这两个尺子相同,要么这二者之间就类似是对称的。即在搜索中是可以类似进行操作的

来的渣比我讨论吧。。。参考别人才写的

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#include<queue>
using namespace std;
const int maxm=58;
const int maxn=1000008;
int a[maxm];
int b[maxm];
int idx;
set<int>    ans;
int shit[maxn];
bool vis[maxn<<5];
struct fuck{
    int state;
    set<int>    ans;
}f;
void bfs()
{
    queue<fuck>    q;
    f.ans.clear();f.ans.insert(0);f.state=0;
    q.push(f);
    int i;
    while(!q.empty())
    {
        f=q.front();q.pop();
    //    printf("%d\n",f.state);
        if(f.state==(1<<idx)-1)
        {
            if(ans.size()==0)
                ans=f.ans;
            else
            {
                if(ans.size()<f.ans.size())    return;
                else    if(ans.size()>f.ans.size())    ans=f.ans;
            /*    else
                {
                    if(*ans.rbegin()>*f.ans.rbegin())
                        ans=f.ans;
                }*/
            }
        }
        if(f.ans.size()==7)    continue;
        for(i=0;i<idx;i++)
        {
            if(f.state&(1<<i))    continue;
            for(set<int>::iterator it =f.ans.begin();
                it!=f.ans.end();it++) 
            {
            //    printf("%dbitch\n",*it);
                if(*it>b[i])
                {
                    fuck p=f;
                    int sum=*it-b[i];
                    for(set<int> :: iterator it2=f.ans.begin();
                    it2!=f.ans.end();it2++)
                    {
                        int nu=abs(*it2-sum);
                    //    printf("bitch%d\n",nu); 
                        if(shit[nu]==-1)    continue;
                        p.state=(p.state|(1<<shit[nu]));
                    }
                    p.ans.insert(sum);
                    if(!vis[p.state])
                    {
                        q.push(p);
                        vis[p.state]=true;
                    }
                }
                if(*it+b[i]<=b[idx-1])
                {
                    fuck p=f;
                    int sum=*it+b[i];
                    for(set<int> :: iterator it2=f.ans.begin();
                    it2!=f.ans.end();it2++)
                    {
                        int nu=abs(*it2-sum);
                        if(shit[nu]==-1)    continue;
                        p.state=(p.state|(1<<shit[nu]));
                    }
                    p.ans.insert(sum);
                    if(!vis[p.state])
                    {
                        q.push(p);
                        vis[p.state]=true;
                    }
                }    
            }
        }
    }
}
int main()
{
    int i,j,n,m;
    int cas=1;
    while(scanf("%d",&n)==1&&n)
    {
        for(i=1;i<=n;i++)
            scanf("%d",&a[i]);
        sort(a+1,a+1+n);
        idx=0;
        memset(vis,false,sizeof(vis));
        memset(shit,-1,sizeof(shit));
        ans.clear();
        for(i=1;i<=n;i++)
        {
            if(shit[a[i]]!=-1)    continue;
            b[idx++]=a[i];
            shit[a[i]]=i;
        }
        for(i=0;i<idx;i++)
            shit[b[i]]=i;
    //    for(i=0;i<idx;i++)    printf("%d ",b[i]);printf("\n");
        bfs();
        set<int>    ::iterator it;
        bool flag=false;
        printf("Case %d:\n",cas++);
        printf("%d\n",ans.size());
        for(it=ans.begin();it!=ans.end();it++)
        {
            if(flag)    printf(" ");
            printf("%d",*it);
            flag=true;
        }
        printf("\n");
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/bitch1319453/p/5011452.html

基于数据挖掘的音乐推荐系统设计与实现 需要一个代码说明,不需要论文 采用python语言,django框架,mysql数据库开发 编程环境:pycharm,mysql8.0 系统分为前台+后台模式开发 网站前台: 用户注册, 登录 搜索音乐,音乐欣赏(可以在线进行播放) 用户登陆时选择相关感兴趣的音乐风格 音乐收藏 音乐推荐算法:(重点) 本课题需要大量用户行为(如播放记录、收藏列表)、音乐特征(如音频特征、歌曲元数据)等数据 (1)根据用户之间相似性或关联性,给一个用户推荐与其相似或有关联的其他用户所感兴趣的音乐; (2)根据音乐之间的相似性或关联性,给一个用户推荐与其感兴趣的音乐相似或有关联的其他音乐。 基于用户的推荐和基于物品的推荐 其中基于用户的推荐是基于用户的相似度找出相似相似用户,然后向目标用户推荐其相似用户喜欢的东西(和你类似的人也喜欢**东西); 而基于物品的推荐是基于物品的相似度找出相似的物品做推荐(喜欢该音乐的人还喜欢了**音乐); 管理员 管理员信息管理 注册用户管理,审核 音乐爬虫(爬虫方式爬取网站音乐数据) 音乐信息管理(上传歌曲MP3,以便前台播放) 音乐收藏管理 用户 用户资料修改 我的音乐收藏 完整前后端源码,部署后可正常运行! 环境说明 开发语言:python后端 python版本:3.7 数据库:mysql 5.7+ 数据库工具:Navicat11+ 开发软件:pycharm
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值