题目:http://www.nocow.cn/index.php/Translate:USACO/shopping

题目很长,大致意思是买n种商品,然后这几种商品按照不同的组合可以有不同的折扣,要我们按照最优的折扣来买东西。看到这道题很自然想到的是背包问题,但是这道题包含的信息明显复杂的多。让我想起了一句话“数据结构是算法的基础,好的数据结构能够很大程度上减少算法的复杂度。”

我使用的第一种方法是,深度搜索剪枝方法,代码如下:

#include <iostream> #include <fstream> #define TYPE 1000 #define SIZE 100 using namespace std; struct Good { int id; int num; }; struct GoodPrivilige { int num; Good g[5]; int value; }; //记录商品价格 int value[TYPE] = {0}; GoodPrivilige p[SIZE]; int pl; Good need[5]; int nl; int result = 0x7FFFFFFF; void calResult(int level, int money) { if (level >= pl) { for (int i=0;i <nl; i ++) { money += need[i].num * value[need[i].id]; } if (money < result) { result = money; } } else { int n = 0; int m = money; while (true) { int flag = true; for (int i=0; i < nl; i ++) { if (need[i].num < 0) { flag = false; break; } }//检验是否有效 //检查有效性 并进行剪枝 if(flag && m < result ) { calResult(level+1,m); } else break; n++; //使用方案的数量 for (int i=0; i < p[level].num; i ++) { int id = p[level].g[i].id; for (int j=0; j < nl; j ++) { if (id == need[j].id) { need[j].num -= p[level].g[i].num; break; }//end if }//end for j }//end for i m += p[level].value; }//end while //还原使用方案的数量 for (int i=0; i < p[level].num; i ++) { int id = p[level].g[i].id; for (int j=0; j < nl; j ++) { if (id == need[j].id) { need[j].num += n * p[level].g[i].num; break; }//end if }//end for j }//end for i }//end else } int main() { ifstream fin("shopping.in"); ofstream fout("shopping.out"); //输入数据 //输入方案 fin >> pl; for (int i =0; i< pl; i ++) { fin >> p[i].num; for (int j=0; j < p[i].num; j ++) { fin >> p[i].g[j].id; fin >> p[i].g[j].num; } fin >> p[i].value; } //输入要购买的物品 fin >> nl; for (int i=0; i < nl; i ++) { fin >> need[i].id >> need[i].num; fin >> value[need[i].id]; } calResult(0,0); fout << result << endl; return 0; }

很可惜的是在Test10的时候,就超时了。

Executing... Test 1: TEST OK [0.000 secs, 3024 KB] Test 2: TEST OK [0.011 secs, 3024 KB] Test 3: TEST OK [0.011 secs, 3024 KB] Test 4: TEST OK [0.000 secs, 3024 KB] Test 5: TEST OK [0.000 secs, 3024 KB] Test 6: TEST OK [0.022 secs, 3024 KB] Test 7: TEST OK [0.022 secs, 3024 KB] Test 8: TEST OK [0.011 secs, 3024 KB] Test 9: TEST OK [0.011 secs, 3024 KB] > Run 10: Execution error: Your program (`shopping') used more than the allotted runtime of 1 seconds (it ended or was stopped at 1.674 seconds) when presented with test case 10. It used 3024 KB of memory.

没办法,只好对其进行优化,跟背包的改进算法是一样的,只是用到了一个5维的数组,用于记录迭代前进的过程。代码如下:

#include <iostream> #include <fstream> #define TYPE 1000 #define SIZE 100 using namespace std; struct Good { int id; int num; }; struct GoodPrivilige { int num; Good g[5]; int value; }; //记录商品价格 int value[TYPE] = {0}; GoodPrivilige p[SIZE]; int pl; Good need[5]; int nl; int result; int table[6][6][6][6][6] = {0}; int getPrivilige(int index,int id) { for (int i=0; i < p[index].num; i ++) { if (id == p[index].g[i].id) { return p[index].g[i].num; } } return 0; } void calResult() { for (int n = 0; n < pl; n ++) { int p1 = getPrivilige(n, need[0].id); int p2 = getPrivilige(n, need[1].id); int p3 = getPrivilige(n, need[2].id); int p4 = getPrivilige(n,need[3].id); int p5 = getPrivilige(n,need[4].id); for (int i=p1; i <= need[0].num; i ++) { for (int j=p2; j <= need[1].num; j ++) { for (int k=p3; k <= need[2].num; k ++) { for (int l =p4; l <= need[3].num; l ++) { for (int m = p5; m <= need[4].num; m ++) { if(table[i][j][k][l][m] > table[i-p1][j-p2][k-p3][l-p4][m-p5] + p[n].value) { table[i][j][k][l][m] = table[i-p1][j-p2][k-p3][l-p4][m-p5] + p[n].value; } }//end m }//end l }//end k }//end j }//end i }//end n; } int main() { ifstream fin("shopping.in"); ofstream fout("shopping.out"); //输入数据 //输入方案 fin >> pl; for (int i =0; i< pl; i ++) { fin >> p[i].num; for (int j=0; j < p[i].num; j ++) { fin >> p[i].g[j].id; fin >> p[i].g[j].num; } fin >> p[i].value; } //输入要购买的物品 fin >> nl; for (int i=0; i < nl; i ++) { fin >> need[i].id >> need[i].num; fin >> value[need[i].id]; } //初始化 for (int i=0; i <= need[0].num; i ++) { for (int j=0; j <= need[1].num; j ++) { for (int k=0; k <= need[2].num; k ++) { for (int l =0; l <= need[3].num; l ++) { for (int m = 0; m <= need[4].num; m ++) { table[i][j][k][l][m] = i * value[need[0].id] + j * value[need[1].id] + k * value[need[2].id] + l * value[need[3].id] + m * value[need[4].id]; }//end m }//end l }//end k }//end j }//end i calResult(); result = table[need[0].num][need[1].num][need[2].num][need[3].num][need[4].num]; fout << result << endl; return 0; }

速度还不错。结果如下:

Executing... Test 1: TEST OK [0.022 secs, 3052 KB] Test 2: TEST OK [0.000 secs, 3052 KB] Test 3: TEST OK [0.000 secs, 3052 KB] Test 4: TEST OK [0.000 secs, 3052 KB] Test 5: TEST OK [0.011 secs, 3052 KB] Test 6: TEST OK [0.000 secs, 3052 KB] Test 7: TEST OK [0.000 secs, 3052 KB] Test 8: TEST OK [0.000 secs, 3052 KB] Test 9: TEST OK [0.011 secs, 3052 KB] Test 10: TEST OK [0.000 secs, 3052 KB] Test 11: TEST OK [0.011 secs, 3052 KB] Test 12: TEST OK [0.000 secs, 3052 KB] All tests OK.

USACO算法系列十五——shoping相关推荐

  1. ELK系列(十五)、Elasticsearch核心原理一篇全搞定

    目录 Lucene 介绍 核心术语 如何理解倒排索引? 检索方式 分段存储 段合并策略 Elasticsearch 核心概念 节点类型 集群状态 3C和脑裂 1.共识性(Consensus) 2.并发 ...

  2. 数学之美 系列十五 繁与简 自然语言处理的几位精英

    数学之美 系列十五 繁与简 自然语言处理的几位精英 我在数学之美系列中一直强调的一个好方法就是简单.但是,事实上,自然语言处理中也有一些特例,比如有些学者将一个问题研究到极致,执著追求完善甚至可以说完 ...

  3. Java 数据结构和算法(十五):无权无向图

    Java数据结构和算法(十五)--无权无向图 前面我们介绍了树这种数据结构,树是由n(n>0)个有限节点通过连接它们的边组成一个具有层次关系的集合,把它叫做"树"是因为它看起 ...

  4. Reflex WMS入门系列十五:Reflex系统上对已经Confirm的Receipt能继续做收货么?

    Reflex WMS入门系列十五:Reflex系统上对已经Confirm的Receipt能继续做收货么? 如下的Receipt已经完成了收货,并且已经confirm了, Cfm(confirm)栏位被 ...

  5. WorldWind学习系列十五:如何切割影像和DEM数据及其在WW中的应用配置

    原文转自:http://www.cnblogs.com/wuhenke/archive/2010/01/03/1638499.html WorldWind学习系列十四中我从代码上分析如何加载DEM数据 ...

  6. 聊聊MySQL的加锁规则《死磕MySQL系列 十五》

    大家好,我是咔咔 不期速成,日拱一卒 本期来聊聊MySQL的加锁规则,知道这些规则后可以判断SQL语句的加锁范围,同时也可以写出更好的SQL语句,防止幻读问题的产生,在能力范围内最大程度的提升MySQ ...

  7. 数据与广告系列十五:商业兴趣标签建模XGboost调优实战

    作者·黄崇远 『数据虫巢』 全文共8210字 题图ssyer.com " 聊聊商业兴趣标签建模,顺带学习下kaggle竞赛神器,快哉." 01 前言 我们来回想下,早在第是一篇&l ...

  8. 【某航】A*算法实现十五数码问题--人工智能课程大作业

    代码链接:github代码 1.问题要求 15数码问题是在4×4方格盘上,放有15个数码,剩下一个位置为空(方便起见,用0表示空),每一空格其上下左右的数码可移至空格.本问题给定初始位置和目标位置,要 ...

  9. Oracle Golden Gate 系列十五 -- GG Trails 说明

    一.Trails 说明 理论知识在系列一里有说明,这里在拿出来看一下: Oracle Golden Gate 系列一 -- GG 架构 说明 http://blog.csdn.net/tianleso ...

最新文章

  1. pandas使用replace函数和正则表达式移除dataframe字符串数据列中尾部指定模式字符串(Removing trailing substring in dataframe)
  2. 将keepalived添加到系统服务中
  3. c语言 void**类型转换,void *和其他指针的转化
  4. 【Julia】Julia v1.5.1 更改Pkg存放位置
  5. 杭电计算机组成实验2(二)超前进位加法器设计实验
  6. [bzoj5301][Cqoi2018]异或序列
  7. cvf命令报错 linux,linux命令大全
  8. 插件 微信 自动 抢红包
  9. Android屏幕共享-基于WebRTC实现
  10. python 爬取taptap热门榜
  11. 前端请求接口出现415错误
  12. 走进龙芯3A3000(二)安装Gentoo N64
  13. celery(分布式任务队列)介绍+在django中异步回调使用+定时任务的使用
  14. 并查集模板详细注释(洛谷P3367)
  15. 免费快速提升网站流量之方法大结合(转摘有修改)
  16. js闭包的理解(传递闭包的通俗理解)
  17. 面试 | 什么是内部类?成员内部类、静态内部类、局部内部类和匿名内部类的区别及作用?
  18. 第三方App接入微信登录 解读 (微信开放平台)
  19. jstree 新建node后,刷新jstree的改变的那一部分
  20. 浅谈Linux内核编程规范与代码风格

热门文章

  1. Android应用图标
  2. 车载导航仪的行业概要
  3. python批量读取excel表格数据_Python读取Excel数据并生成图表过程解析
  4. 2023认证杯数学建模挑战赛C题心脏危险完整原创论文讲解
  5. 第七届全国信息技术应用水平大赛模拟题 JAVA程序设计
  6. fckeditor编辑器漏洞
  7. 游戏平台移植经验(Android)
  8. 博弈论——浙江大学蒋文华笔记
  9. python7(文件,join方法,jieba,wordcloud词云绘制)
  10. 百度地图李东旻:中国地图行业最终只会剩下一两个玩家/阿里云CDN再降价25%