UVa1321/LA2925 Dice contest

UVa1321/LA2925 Dice contest

  • 题目链接
  • 题意
  • 分析
  • 测试数据
  • AC 代码

题目链接

   本题是2003年icpc欧洲区域赛中欧赛区的D题

题意

   骰子的六面展开图如下,现在把骰子的六个面赋予一套权重 w i ( 1 ≤ w i ≤ 50 , 1 ≤ i ≤ 6 ) w_i(1\le w_i \le 50,1\le i\le 6) wi(1wi50,1i6),每翻转一次骰子的代价是翻转转后顶面的权重。
dice
   有一个4行无数列的网格桌子,初始时骰子顶面是1点,正面是2点(面向玩家),放置在 ( x 1 , y 1 ) (x_1,y_1) (x1,y1)格子处,每次可以将骰子翻转到上下左右之一的相邻格子,翻转的代价是反转后顶面的权重,求将骰子翻转到 ( x 2 , y 2 ) (x_2,y_2) (x2,y2)格子处的最小代价 ( − 1000000000 ≤ x 1 , x 2 ≤ 1000000000 , 1 ≤ y 1 , y 2 ≤ 4 ) (-1000000000\le x_1,x_2\le 1000000000,1\le y_1,y_2\le 4) (1000000000x1,x21000000000,1y1,y24)

分析

   题意倒是好理解,但是题目的sample数据和uDebug上标程的输出不一致,巨坑。

1 2 3 8 1 4
-1 1 0 2

   题目说sample输出是7,然而标程输出是5,反而下面这个数据标程才是输出7。

1 2 8 3 1 4
-1 1 0 2

   这其实就是行从上到下还是从下到上编号的区别,如下图所示。
dice1
   可见行从下往上是sample的输出是7,行从上往下输出是5(和标程相同),因此采用行从上往下处理。

   骰子不管在哪个网格,有24种状态,乘上行数4,总共96,起点到终点的横坐标跨度 d x dx dx可能很大,考虑稀疏表/倍增法可将复杂度优化到 O ( 9 6 3 log ⁡ d x ) O(96^3\log dx) O(963logdx)(不超过 3 × 1 0 7 ) 3\times 10^7) 3×107):记 a [ y 1 ] [ s 1 ] [ y 2 ] [ s 2 ] [ i ] a[y_1][s_1][y_2][s_2][i] a[y1][s1][y2][s2][i]表示骰子在第 y 1 y_1 y1行状态为 s 1 s_1 s1,翻转到第 y 2 y_2 y2行状态为 s 2 s_2 s2且横向移动量为 2 i 2^i 2i 1 ≤ y 1 , y 2 ≤ 4 , 0 ≤ s 1 , s 2 < 24 , 0 ≤ i < 31 1\le y_1,y_2\le 4,0\le s_1,s_2<24,0\le i<31 1y1,y24,0s1,s2<24,0i<31)的最小代价。

   这就需要求出初始横向移动量为1的最小代价 a [ y 1 ] [ s 1 ] [ y 2 ] [ s 2 ] [ 0 ] a[y_1][s_1][y_2][s_2][0] a[y1][s1][y2][s2][0],考虑到向右(或者向左)移动量为1的最小代价可能通过反方向移动更大的量再翻转回来(或者从其它行移动更大的量再翻转回来)而取得,如果横向移动动范围的极限能分析出来,并且极限比较小,则可以利用Dijkstra求得。

   一个感性的结论是:横向移动范围的极限是19(向左/向右9,加上0),因为绕骰子三条轴任意一条翻转的不同权重最多也就4种并且顺/逆时针连续翻转以4为周期,如果绕某轴顺/逆时针净翻转(有可能顺时针翻转了2次逆时针翻又转回来一次,最终顺时针净翻转了一次)了4次以上最终横向移动量达到1,完全可以净翻转少于4次达到同样的结果并且代价更小,三条不同轴总共最多净翻转9次,即便全部贡献给横向移动(纵向移动也可能占用净翻转),向左/向右的最大移动量也才9。

   因此确实可以用Dijkstra求出初始横向移动量为1的最小代价:记 d [ y 1 ] [ s 1 ] [ y 2 ] [ s 2 ] [ l ] d[y_1][s_1][y_2][s_2][l] d[y1][s1][y2][s2][l]表示骰子在第 y 1 y_1 y1行状态为 s 1 s_1 s1,翻转到第 y 2 y_2 y2行状态为 s 2 s_2 s2且横向移动量为 l l l的当前最小代价( 1 ≤ y 1 , y 2 ≤ 4 , 0 ≤ s 1 , s 2 < 24 , 0 ≤ l < 19 1\le y_1,y_2\le 4,0\le s_1,s_2< 24,0\le l< 19 1y1,y24,0s1,s2<24,0l<19,如果横向移动量是负数 x x x,则用 19 + x 19+x 19+x来替代),对每个出发结点 ( y 1 , s 1 ) (y_1,s_1) (y1,s1),将其和初始值 d [ y 1 ] [ s 1 ] [ y 1 ] [ s 1 ] [ 0 ] = 0 d[y_1][s_1][y_1][s_1][0]=0 d[y1][s1][y1][s1][0]=0入优先级队列跑一遍Dijkstra,最终 d [ y 1 ] [ s 1 ] [ y 2 ] [ s 2 ] [ 1 ] d[y_1][s_1][y_2][s_2][1] d[y1][s1][y2][s2][1]就是所求。

测试数据

   给一份CERC 2003官方的整套题解和测试数据。

AC 代码

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;

#define L 19
long long d[4][24][4][24][L], a[4][24][4][24][31], e[2][4][24]; bool f[4][24][L];
int c[][2] = {{2, 3}, {6, 3}, {6, 5}, {6, 2}, {6, 4}, {2, 4}}, w[7], x1, y1, x2, y2;

struct node {
    int y, s, x; long long d;
    bool operator< (const node &rhs) const {
        return d > rhs.d;
    }
} t;

int encode(int t, int f) {
    --t;
    return (t<<2) + (f == c[t][0] ? 0 : (f == c[t][1] ? 1 : (f == 7-c[t][0] ? 2 : 3)));
}

void decode(int s, int &t, int &f) {
    t = s>>2; f = s&3; f = f < 2 ? c[t++][f] : 7-c[t++][f-2];
}

void roll(int s, int d, int &t, int &f) {
    int t0, f0; decode(s, t0, f0); int (&e)[2] = c[t0-1];
    if (d == 0) t = f0, f = 7-t0;
    else if (d == 1) t = 7-f0, f = t0;
    else if (d == 2) t = f0 == e[0] ? 7-e[1] : (f0 == e[1] ? e[0] : (f0 == 7-e[0] ? e[1] : 7-e[0])), f = f0;
    else t = f0 == e[0] ? e[1] : (f0 == e[1] ? 7-e[0] : (f0 == 7-e[0] ? 7-e[1] : e[0])), f = f0;
}

long long solve() {
    for (int i=1; i<7; ++i) cin >> w[i];
    cin >> x1 >> y1 >> x2 >> y2; x2 -= x1; --y1; --y2;
    priority_queue<node> q; memset(d, 1, sizeof(d));
    for (int i=0; i<4; ++i) for (int j=0; j<24; ++j) {
        long long (&r)[4][24][L] = d[i][j]; q.push({i, j, 0, r[i][j][0] = 0}); memset(f, 0, sizeof(f));
        while (!q.empty()) {
            t = q.top(); q.pop(); int y = t.y, s = t.s, x = t.x > (L>>1) ? t.x-L : t.x; long long d = t.d;
            if (f[y][t.x][s]) continue;
            f[y][t.x][s] = true;
            for (int k=0; k<4; ++k) {
                int u = k<2 ? (k ? y-1 : y+1) : y, v = k<2 ? x : (k>2 ? x+1 : x-1), t, f, g; roll(s, k, t, f);
                if (u<0 || u>3 || abs(v) > (L>>1)) continue;
                if (v < 0) v += L;
                if (d + w[t] < r[u][g = encode(t, f)][v]) q.push({u, g, v, r[u][g][v] = d + w[t]});
            }
        }
    }
    for (int y=0; y<4; ++y) for (int s=0; s<24; ++s) e[0][y][s] = d[y1][0][y][s][0];
    int b = x2<0 ? L-1 : 1, k = 0, c = 0; x2 = abs(x2); memset(a, 1, sizeof(a));
    for (unsigned int i=x2; (1<<k) <= i; ++k);
    for (int y=0; y<4; ++y) for (int s=0; s<24; ++s) for (int u=0; u<4; ++u) for (int v=0; v<24; ++v)
        a[y][s][u][v][0] = d[y][s][u][v][b];
    for (int w=1; w<k; ++w) for (int y=0; y<4; ++y) for (int s=0; s<24; ++s)
    for (int u=0; u<4; ++u) for (int v=0; v<24; ++v) for (int i=0; i<4; ++i) for (int j=0; j<24; ++j)
        a[y][s][u][v][w] = min(a[y][s][u][v][w], a[y][s][i][j][w-1] + a[i][j][u][v][w-1]);
    if (k--) {
        for (; x2 && k>=0; --k) if ((1<<k) <= x2) {
            for (int y=0; y<4; ++y) for (int s=0; s<24; ++s) {
                long long &r = e[c^1][y][s] = 200000000000;
                for (int u=0; u<4; ++u) for (int v=0; v<24; ++v) r = min(r, e[c][u][v] + a[u][v][y][s][k]);
            }
            c ^= 1; x2 -= 1<<k;
        }
    }
    long long ans = e[c][y2][0];
    for (int i=1; i<24; ++i) ans = min(ans, e[c][y2][i]);
    return ans;
}

int main() {
    int t; cin >> t;
    for (int k=0; k<t; ++k) {
        if (k) cout << endl;
        cout << solve() << endl;
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/770856.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

米国政府呼吁抛弃 C 和 C++

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「C的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01; 很多观点认为C 或 C永远不可被…

同步互斥与通信

目录 一、同步与互斥的概念 二、同步与互斥并不简单 三、各类方法的对比 一、同步与互斥的概念 一句话理解同步与互斥&#xff1a;我等你用完厕所&#xff0c;我再用厕所。 什么叫同步&#xff1f;就是&#xff1a;哎哎哎&#xff0c;我正在用厕所&#xff0c;你等会。 什…

nginx.conf配置参数解析

nginx配置文件解析 /usr/local/nginx/conf vim /etc/security/limits.conf #配置生效只能重新启动* soft nproc 65535 #能打开的进程最大数是软限制655335,65535是最大值 * hard nproc 65535 * soft nofile 65535 # 进程打开文件数的最大值65535 * hard nof…

最新美联储会议纪要:通胀降温,但不急于降息!

KlipC报道&#xff1a;当地时间周三&#xff0c;美联储公布了6月货币政策会议纪要。纪要显示&#xff0c;数据表明有通胀放缓的迹象&#xff0c;但如果降息需要更多的证据。此外&#xff0c;多位与会者表示&#xff0c;货币政策应随时准备应对意外的经济疲软。 会议纪要显示&a…

python-字典

为什么需要字典 字典的定义 字典数据的获取 字典的嵌套 嵌套字典的内容获取 字典的注意事项&#xff1a; 字典的常用操作 新增元素 更新元素 删除元素 清空字典 汇总 字典的特点

收银系统源码-收银台营销功能-定时折扣

1. 功能描述 定时折扣&#xff1a;在特定的时间段&#xff0c;将商品以打折的方式在收银台售卖&#xff0c;例如生鲜行业&#xff0c;由于生鲜是易耗品&#xff0c;很多门店晚上都会通过打折的方式进行促销&#xff1b; 2.适用场景 新门店开业、门店周年庆、节假日等特定时间…

深度分析和对比本地大语言模型Ollama和LocalAI

前言 在充满活力的人工智能&#xff08;AI&#xff09;世界中&#xff0c;开源工具已成为开发人员和组织利用LLM&#xff08;大型语言模型&#xff09;力量的重要资源。这些工具通过提供对高级LLM模型的访问权限&#xff0c;使各种用户能够构建创新和前沿的解决方案。在众多可…

springboot @configuration注解的配置, @bean注解方法a, 在@bean注解 getb(){}需要注入a

深度解析Configuration注解 /*** General purpose AOP callback. Used when the target is dynamic or when the* proxy is not frozen.*/private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {private final AdvisedSupport advised;…

实验九 存储过程和触发器

题目 创建并执行一个无参数的存储过程proc_product1&#xff0c;通过该存储过程可以查询商品类别名称为“笔记本电脑”的商品的详细信息&#xff1a;包括商品编号、商品名称、品牌、库存量、单价和上架时间信息 2、创建并执行一个带输入参数的存储过程proc_product2&#xff…

Rethinking Federated Learning with Domain Shift: A Prototype View

CVPR2023,针对分布式数据来自不同的域时,私有模型在其他域上表现出退化性能(具有域转移)的问题。提出用于域转移下联邦学习的联邦原型学习(FPL)。核心思想是构建集群原型和无偏原型,提供富有成效的领域知识和公平的收敛目标。将样本嵌入拉近到属于相同语义的集群原型,而…

【前端】IntersectionObserver 实现图片懒加载和无限滚动

【前端】IntersectionObserver 实现图片懒加载和无限滚动 在前端开发中&#xff0c;性能优化是一个重要的考量因素。随着现代网页和应用的复杂性增加&#xff0c;确保页面快速加载和流畅运行变得越来越重要。本文将介绍一种强大的工具——IntersectionObserver API&#xff0c…

智胜未来:AI如何重塑SaaS用户增长战略

在当今这个数字化时代&#xff0c;SaaS&#xff08;软件即服务&#xff09;已成为企业运营的重要支柱&#xff0c;而人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;正以前所未有的方式重塑着SaaS行业的面貌&#xff0c;特别是对其用户增长战略产生了深远影响。…

每日一题——Python实现PAT乙级1005 继续(3n+1)猜想(举一反三+思想解读+逐步优化)五千字好文

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 我的写法 代码逻辑概述 时间复杂度分析 空间复杂度分析 总结 我要更强 代码优化点…

Openwrt路由器部分ipv6公网地址无法访问的问题

路由器是Openwrt&#xff0c;终端访问ipv6地址经常有些能访问&#xff0c;有些不能访问&#xff0c;一开始以为是运营商问题&#xff0c;后面ssh到openwrt发现所有访问都正常。 查阅资料后才知道是MTU设置问题&#xff0c;Openwrt 默认MTU是1492&#xff0c;使用IPV6应减少60个…

Word文档中公式的常用操作

一、参考资料 二、常用操作 插入公式 Alt 多行公式 Shift Enter 多行公式对齐 WORD Tips: 多行公式编辑及对齐 word自带公式等号对齐&#xff08;可任意符号处对齐&#xff09; 多行公式按照 为基准对齐。 拖动鼠标选中整个公式点击右键&#xff0c;选择【对齐点(…

[激光原理与应用-97]:激光焊接焊中检测系统系列介绍 - 1 - 什么是焊接以及传统的焊接方法

目录 一、什么是焊接 1.1 概述 1.2 基本原理 二、传统的焊接技术与方法 2.1 手工电弧焊&#xff1a; 1、定义与原理 2、特点 3、焊条类型 4、应用领域 5、安全注意事项 2.2 气体保护焊&#xff1a; 1、原理与特点 2、应用领域 3、气体选择 4、注意事项 2.3 电阻…

C++ 文达校内党员管理系统-计算机毕业设计源码20855

目 录 摘要 1 绪论 1.1研究背景与意义 1.2国内外研究现状 1.3论文结构与章节安排 2 文达校内党员管理系统系统分析 2.1 可行性分析 2.2 系统功能分析 2.2.1 功能性分析 2.2.2 非功能性分析 2.3 系统用例分析 2.4 系统流程分析 2.4.1 数据流程 2.5.2 业务流程 2.…

CPU/内存/综合性能评估工具汇总-3:unixbench

目录 一、概括二、UnixBench 一、概括 嵌入式开发中对要设计的产品、立项的项目进行设计时&#xff0c;往往需要对关键芯片进行性能评估&#xff0c;本文主要总结基于linux系统的产品在性能评估时的工具使用总结&#xff0c;在aarch64(arm64平台下测试)&#xff0c;板卡根文件…

前端学习(三)CSS介绍及选择符

##最近在忙期末考试&#xff0c;因此前端笔记的梳理并未及时更新。在学习语言过程中&#xff0c;笔记的梳理对于知识的加深very vital.因此坚持在明天学习新知识前将笔记梳理完整。 主要内容&#xff1a;CSS介绍及选择符 最后更新时间&#xff1a;2024/7/4 目录 内容&#x…

Redis 7.x 系列【15】持久化机制之 RDB

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Redis 版本 7.2.5 源码地址&#xff1a;https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 概述2 执行原理3. 配置项3.1 save3.2 stop-writes-on-bgsave-error3.3 rdbcompress…
最新文章