ZCMU - 2165: 黄金矿工

简介: ZCMU - 2165: 黄金矿工

题目链接


题目大意:略。


解题思路:DFS --> TLE;难点在于如何把直线问题转换成01背包问题:在相同角度基础上并且到原点距离短的优先在前排序后:

AC-1:先把相等角度的情况下,后者加上前者的 t 和 v,把它看成一个整体的状态来思考,最后通过 mk[i] 来控制跳跃到上一个不相等的元素。

AC-2:将在后面的元素的时间加上相邻前面元素(在一条直线上)的时间,可以理解成离散状态,该点需要的时间是ti+=t(i-1),但是这里需要另外声明临时变量,不可以用数组来加否则会影响dp结果。


TLE 代码


/

#include<bits/stdc++.h>
#include<cmath>
#define mem(a,b) memset(a,b,sizeof a);
using namespace std;
typedef long long ll;
struct node
{
    double a;
    int t,v,s;
};
node nds[300];
int vis[300];
int n,m,x,y,rs,ans,pre;
int cmp(node n1,node n2)
{
    if(n1.a==n2.a)
        return n1.s<n2.s;
    return n1.a<n2.a;
}
void init()
{
    ans=rs=0;
    mem(vis,0);
    nds[0].a=0;
}
void dfs(int k)
{
    if(k>m)
    {
        rs=max(rs,ans-pre);
        return;
    }
    for(int i=1;i<=n;i++)
    {
        if(vis[i]==0 && (nds[i-1].a==nds[i].a&&vis[i-1]==1 || nds[i-1].a!=nds[i].a))
        {
            vis[i]=1;
            ans+=nds[i].v;
            pre=nds[i].v;
            dfs(k+nds[i].t);
            ans-=nds[i].v;
            vis[i]=0;
        }
    }
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        init();
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d%d%d",&x,&y,&nds[i].t,&nds[i].v);
            nds[i].a=y*1.0/x;
            nds[i].s=y*y+x*x;
        }
        sort(nds+1,nds+1+n,cmp);
        dfs(0);
        printf("%d\n",rs);
    }
    return 0;
}

AC-1 代码

#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof a)
using namespace std;
typedef long long ll;
struct node
{
    double a;
    int t,v,s;
};
node nds[300];
int n,m,x,y;
int dp[300][40000+100];
int cmp(node n1,node n2)
{
    if(n1.a==n2.a)
        return n1.s<n2.s;
    return n1.a<n2.a;
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        mem(dp,0);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d%d%d",&x,&y,&nds[i].t,&nds[i].v);
            nds[i].a=y*1.0/x;
            nds[i].s=y*y+x*x;
        }
        sort(nds+1,nds+1+n,cmp);
        int idx=1,mk[300];
        mk[1]=1; // 与 nds[i] 同步
        for(int i=2;i<=n;i++)
            if(nds[i].a!=nds[i-1].a)
                mk[i]=++idx;
            else
                mk[i]=idx;
        for(int i=1;i<=n;i++)
        {
            if(nds[i].a==nds[i-1].a)
            {
                nds[i].t+=nds[i-1].t, nds[i].v+=nds[i-1].v;
                for(int j=m;j>=0;j--)
                {
                    if(j>=nds[i].t)
                        dp[i][j]=max(dp[i-1][j],dp[mk[i]-1][j-nds[i].t]+nds[i].v); // mk[i]-1 可以打印dp看看分析下,因为要跳过前一个相同的,因为已经把前一个的t和v加上去了,表示把多个看为一个整体
                    else
                        dp[i][j]=dp[i-1][j];
                }
            }
            else
                for(int j=m;j>=0;j--)
                {
                    if(j>=nds[i].t)
                        dp[i][j]=max(dp[i-1][j],dp[i-1][j-nds[i].t]+nds[i].v);
                    else
                        dp[i][j]=dp[i-1][j];
                }
        }
//        for(int i=0;i<=n;i++)
//        {
//            for(int j=0;j<=m;j++)
//            {
//                printf("%d ",dp[i][j]);
//            }
//            puts("");
//        }
        printf("%d\n",dp[n][m]);
    }
    return 0;
}

AC-2 代码:    

#include<bits/stdc++.h>
#include<cmath>
#define mem(a,b) memset(a,b,sizeof a)
using namespace std;
typedef long long ll;
struct node
{
    double a;
    int t,v,s;
};
node nds[300];
int n,m,x,y;
int dp[40000+100];
int cmp(node n1,node n2)
{
    if(n1.a==n2.a)
        return n1.s<n2.s;
    return n1.a<n2.a;
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        mem(dp,0);
        for(int i=0;i<n;i++)
        {
            scanf("%d%d%d%d",&x,&y,&nds[i].t,&nds[i].v);
            nds[i].a=y*1.0/x;
            nds[i].s=hypot(x,y);
//            nds[i].s=y*y+x*x;
        }
        sort(nds,nds+n,cmp);
        int t=0;
        for(int i=0;i<n;i++)
        {
//            if(nds[i].a==nds[i-1].a) // 因为会影响到下面计算 j-nds[i].t 的结果,功能上是与下面?:代码一样的
//                nds[i].t+=nds[i-1].t;
            nds[i].a==nds[i-1].a?t+=nds[i].t:t=nds[i].t;
            for(int j=m;j>=t;j--)
                dp[j]=max(dp[j],dp[j-nds[i].t]+nds[i].v);
        }
        printf("%d\n",dp[m]);
    }
    return 0;
}
目录
相关文章
Funcode实现黄金矿工
Funcode实现黄金矿工
|
Web App开发 前端开发 API
|
Android开发
Android开源项目:捕鱼达人游戏源代码
 Android开源项目:捕鱼达人游戏源代码 这是一个Android上的开源项目:捕鱼达人游戏源代码,github上的地址链接是:https://github.com/zhangphil/Android-BuYuDaRenGame.git 内容和捕鱼达人类似。
3410 0
|
3天前
|
弹性计算 人工智能 安全
对话 | ECS如何构筑企业上云的第一道安全防线
随着中小企业加速上云,数据泄露、网络攻击等安全威胁日益严重。阿里云推出深度访谈栏目,汇聚产品技术专家,探讨云上安全问题及应对策略。首期节目聚焦ECS安全性,提出三道防线:数据安全、网络安全和身份认证与权限管理,确保用户在云端的数据主权和业务稳定。此外,阿里云还推出了“ECS 99套餐”,以高性价比提供全面的安全保障,帮助中小企业安全上云。
对话 | ECS如何构筑企业上云的第一道安全防线
|
11天前
|
调度 云计算 芯片
云超算技术跃进,阿里云牵头制定我国首个云超算国家标准
近日,由阿里云联合中国电子技术标准化研究院主导制定的首个云超算国家标准已完成报批,不久后将正式批准发布。标准规定了云超算服务涉及的云计算基础资源、资源管理、运行和调度等方面的技术要求,为云超算服务产品的设计、实现、应用和选型提供指导,为云超算在HPC应用和用户的大范围采用奠定了基础。
179620 22
|
20天前
|
人工智能 自然语言处理 前端开发
从0开始打造一款APP:前端+搭建本机服务,定制暖冬卫衣先到先得
通义灵码携手科技博主@玺哥超carry 打造全网第一个完整的、面向普通人的自然语言编程教程。完全使用 AI,再配合简单易懂的方法,只要你会打字,就能真正做出一个完整的应用。
9612 28
|
6天前
|
机器学习/深度学习 分布式计算 供应链
阿里云先知安全沙龙(上海站) ——大模型基础设施安全攻防
大模型基础设施的安全攻防体系涵盖恶意输入防御和基础设施安全,包括框架、三方库、插件、平台、模型和系统安全。关键漏洞如CVE-2023-6019(Ray框架命令注入)、CVE-2024-5480(PyTorch分布式RPC)及llama.cpp中的多个漏洞,强调了代码安全性的重要性。模型文件安全方面,需防范pickle反序列化等风险,建议使用Safetensors格式。相关实践包括构建供应链漏洞库、智能化漏洞分析和深度检测,确保全方位防护。
|
1天前
|
机器学习/深度学习 人工智能 安全
阿里云先知安全沙龙(武汉站) ——AI赋能软件漏洞检测,机遇, 挑战与展望
本文介绍了漏洞检测的发展历程、现状及未来展望。2023年全球披露的漏洞数量达26447个,同比增长5.2%,其中超过7000个具有利用代码,115个已被广泛利用,涉及多个知名软件和系统。文章探讨了从人工审计到AI技术的应用,强调了数据集质量对模型性能的重要性,并展示了不同检测模型的工作原理与实现方法。此外,还讨论了对抗攻击对模型的影响及提高模型可解释性的多种方法,展望了未来通过任务大模型实现自动化漏洞检测与修复的趋势。
|
5天前
|
机器学习/深度学习 人工智能 安全
通义视觉推理大模型QVQ-72B-preview重磅上线
Qwen团队推出了新成员QVQ-72B-preview,这是一个专注于提升视觉推理能力的实验性研究模型。提升了视觉表示的效率和准确性。它在多模态评测集如MMMU、MathVista和MathVision上表现出色,尤其在数学推理任务中取得了显著进步。尽管如此,该模型仍存在一些局限性,仍在学习和完善中。