洛谷 P1336 最佳课题选择 题解
P1336 最佳课题选择 题解
状态:考虑\(f_{i,j}\)表示前\(i\)种论文里面,一共写了\(j\)篇,的最少花费时间。
转移策略:我们一次考虑每一种论文写多少篇。假设写\(k\)篇,\(k \in [0,j] \cap \mathbb{Z}\) ,有转移方程:
\]
其中
\]
可以做记忆化优化,因为多次访问同一个\(cost(i,k)\)。
初始化:我们考虑选0篇无论怎样花费为0,选0种论文但多于0篇一定是不可能的,花费为Inf,再加上转移中要取min的缘故,我们初始化为:
f_{i,j}=\left\{
\begin{array}{}
0 & ,j=0\\
+ \inf &, j \neq 0\\
\end{array}
\right
.
\end{equation*}
\]
相关变量范围见代码。
最后,我们就可以开滚动数组,或者倒序\(j\)优化掉一维。
代码在文末。
这里和01背包及无限背包做个对比。
01背包的转移选择策略,是一个一个选(同时也是一种一种选,因为一种里面只有一个)。转移方程:
\]
无限背包的转移选择策略,是在一种里面一个个选。转移方程:
\]
可以看到两者细微的差别在,选物品的时候,01背包访问\(i-1\),无限背包访问\(i\),所以可以把其中一个维度压缩掉之后,01反着做,无限正着做。
本题目有两点不同:
第一,本题相当于“选择超过某价值的物品,使得容量需要量最小”,把状态的内外对换了一对。
第二,本题目中,如果选了前面一个,那么后面再选的时候,贡献会不一样,因为时间贡献是幂级的而非线性的。类比到无限背包中就是“选的越多,价值越少”,已经选了多少会影响到后面选的东西。选同一个东西的贡献,在不同情况下不一样。
于是,按照无限背包“一个一个”选的策略,就会涉及到之前的选择情况,我们尝试把第\(i\)种选择数目\(k\)加入到状态中,有
f_{i,j,k(k \leq j)}=\left\{
\begin{array}{}
f_{i,j-1,k-1} - cost(i,k-1) + cost(i,k) & ,k \neq 0\\
min(f_{i-1,j,l}), l \in [0,j] \cap \mathbb{Z} &, k = 0\\
\end{array}
\right
.
\end{equation*}
\]
这样是正确的,但是我们发现大多数的状态被浪费了,因为\(k \neq 0\) 的时候只有一种选择。
还有一种方式是把\(f_{i,j}\)中选择了多少个第i种论文,另存为\(g_{i,j} = k\),于是我们有转移方程(错误的):
f_{i,j}=min\left(
\begin{array}{}
f_{i,j-1} - cost(i,g_{i,j-1}) + cost(i,g_{i,j}), g_{i,j} = g_{i,j-1} + 1 ,\\
f_{i-1,j}, g(i,j) = 0
\end{array}
\right)
\end{equation*}
\]
这个转移方程看上去好像是对的,因为就是按照无限背包的思路改的,但实际上是错误的,提交后只能有10分。因为理论上这种转移方程只能处理线性的\(cost(i,k)\),即\(b_{i} = 1\)或\(b_{i} = 0\)
我们和无限背包进行对比:假设有\(f_{1,1} = 12\),\(f_{1,2} = 24\),\(f_{2,1} = 2\),那么对于无限背包问题,有:
\because f_{2,1} = max(f_{1,1},f_{2,0} + v_{2}) \neq f_{1,1}\\
\therefore f_{2,1} \geq f_{1,1}\\
\therefore f_{2,1} + v_{2} \geq f_{1,1} + v_{2}
\]
因此\(f_{1,1} + v_{2}\)不会影响\(f_{2,1} + v_{2}\)对\(f_{2,2}\)可能的贡献,也就是不可能贡献(被max掉了)。
但是在这个问题中,我们令\(w_{i,k} = cost(i,k) - cost(i,k-1)\),有:
\because f_{2,1} = min(f_{1,1},f_{2,0} + w_{2,2}) \neq f_{1,1}\\
\therefore f_{2,1} \leq f_{1,1}\\
\therefore f_{2,1} + w_{2,2} \quad? \quad f_{1,1} + w_{2,1}
\]
可以发现我们无法判断\(f_{1,1} + w_{2,1}\)对于\(f_{2,2}\)是否有贡献,其根源在于对于同一个\(i\),\(w_{i,k}\)是可能不同的,因此不等式失效,即在这种状态和转移方程下,不满足最优子结构。因此DP失效。
(这也说明,一个可DP的问题是存在“最优子结构”“无后效性”,只有特定的方式去“成立”这些性质才能DP,不是随便搞一搞就一定可以DP的)
也就是说,在无限背包问题中,我们把一个物品拿走,从规模更小的状态中转移,这个物品的贡献是确定的,决定“拿走”这一选择中的最优解,就只能是承接之前的最优解。
然而在这个问题中,如果我们把一个物品拿走,从规模更小的状态中转移时,这个物品的贡献是不确定的,也就是说除了最优解以外,次有解也有可能贡献出更好的结果,因此“最优子结构失效了”。
因此,我们在考虑状态和状态转移方程时,可以灵活更改状态、转移方式和策略、记录信息等等,同时也要按照普适状况考虑转移的合法性和具体转移方法。
标准AC代码:
#include <bits/stdc++.h>
#define N (int)(205)
#define M (int)(25)
using namespace std;
typedef long long LL;
int n,m;
LL f[N];
LL a[M],b[M];
LL p[M][N];
LL cost(int i, int k)
{
if(p[i][k] == -1)
return p[i][k] = a[i] * pow(k,b[i]);
else
return p[i][k];
}
int main()
{
memset(p,-1,sizeof(p));
memset(f,0x7f,sizeof(f));
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >> n >> m;
for(int i = 1;i <= m;i++) cin >> a[i] >> b[i];
f[0] = 0;
for(int i = 1;i <= m;i++)
{
for(int j = n;j >= 1;j--)
{
for(int k = 0;k <= j;k++)
{
f[j] = min(f[j],f[j-k] + cost(i,k));
}
}
}
cout << f[n];
return 0;
}
另一种AC的代码:
#include <bits/stdc++.h>
#define N (int)(205)
#define M (int)(25)
using namespace std;
typedef long long LL;
int n,m;
LL f[M][N][N];
LL a[M],b[M];
LL p[M][N];
LL cost(int i, int k)
{
if(p[i][k] == -1)
return p[i][k] = a[i] * pow(k,b[i]);
else
return p[i][k];
}
int main()
{
memset(p,-1,sizeof(p));
memset(f,0x7f,sizeof(f));
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >> n >> m;
for(int i = 1;i <= m;i++) cin >> a[i] >> b[i];
for(int i = 0;i <= m;i++) f[i][0][0] = 0;
for(int i = 1;i <= m;i++)
{
for(int j = 1;j <= n;j++)
{
for(int l = 0;l <= j;l++)
{
f[i][j][0] = min(f[i][j][0],f[i-1][j][l]);
}
for(int k = 1;k <= j;k++)
{
f[i][j][k] = f[i][j-1][k-1] - cost(i,k-1) + cost(i,k);
}
}
}
LL ans = 1e18;
for(int k = 0;k <= n;k++)
ans = min(ans,f[m][n][k]);
cout << ans;
return 0;
}
洛谷 P1336 最佳课题选择 题解的更多相关文章
- 洛谷 P1336 最佳课题选择
P1336 最佳课题选择 题目提供者 yeszy 标签 动态规划 福建省历届夏令营 传送门 难度 尚无评定 题目描述 Matrix67要在下个月交给老师n篇论文,论文的内容可以从m个课题中选择.由于课 ...
- P1336 最佳课题选择
P1336 最佳课题选择 题目描述 Matrix67要在下个月交给老师n篇论文,论文的内容可以从m个课题中选择.由于课题数有限,Matrix67不得不重复选择一些课题.完成不同课题的论文所花的时间不同 ...
- luogu P1336 最佳课题选择
题目描述 Matrix67要在下个月交给老师n篇论文,论文的内容可以从m个课题中选择.由于课题数有限,Matrix67不得不重复选择一些课题.完成不同课题的论文所花的时间不同.具体地说,对于某个课题i ...
- luogu P1336 最佳课题选择 |背包dp
题目描述 Matrix67要在下个月交给老师n篇论文,论文的内容可以从m个课题中选择.由于课题数有限,Matrix67不得不重复选择一些课题.完成不同课题的论文所花的时间不同.具体地说,对于某个课题i ...
- 洛谷P1783 海滩防御 分析+题解代码
洛谷P1783 海滩防御 分析+题解代码 题目描述: WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和 ...
- 洛谷P4047 [JSOI2010]部落划分题解
洛谷P4047 [JSOI2010]部落划分题解 题目描述 聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是拉帮结派形成属于自己的部落,不同的部落 ...
- 洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈)
洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1311990 原题地址:洛谷P1155 双栈排序 ...
- 02题解-洛谷 P2395 BBCode转换Markdown 题解
洛谷 P2395 BBCode转换Markdown 题解 题目传送门: here. 一道毒瘤的大模拟,给了你一部分的 BBCode 和 Markdown 语法,叫你转换.如下表: BBCode Mar ...
- 浅谈分治 —— 洛谷P1228 地毯填补问题 题解
如果想看原题网址的话请点击这里:地毯填补问题 原题: 题目描述 相传在一个古老的阿拉伯国家里,有一座宫殿.宫殿里有个四四方方的格子迷宫,国王选择驸马的方法非常特殊,也非常简单:公主就站在其中一个方格子 ...
- 洛谷10月月赛II题解
[咻咻咻] (https://www.luogu.org/contestnew/show/11616) 令人窒息的洛谷月赛,即将参加NOIp的我竟然只会一道题(也可以说一道也不会),最终145的我只能 ...
随机推荐
- 自建CA和公共CA有什么不同?
据统计,全球有数百个公共CA,通常它们是按国家地区进行划分的.这类CA受大众的广泛认可和使用,也被称为公共信任的证书颁发机构.但是由于一些大型企业拥有许多站点,为了更轻松高效的管理以及考虑到维护成本, ...
- 2021-02-08:给定一个字符串str,请问这个字符串的最长回文子序列长度是多少?
2021-02-08:给定一个字符串str,请问这个字符串的最长回文子序列长度是多少? 福哥答案2021-02-08: 自然智慧即可.1.原序列和反序列求公共子序列.无代码.2.递归.有代码.3.动态 ...
- Python MQTT客户端 paho-mqtt
Python中MQTT Python有许多优秀的MQTT客户端,比较有代表性的有paho-mqtt.hbmqtt.gmqtt等,各有特色 paho-mqtt 有着最优秀的文档,代码风格易于理解,同时有 ...
- LOTO示波器如何测试阻抗的频响曲线
LOTO示波器如何测试阻抗的频响曲线 模块的输入输出端口,在电路分析上,一般简单表征为电阻来进行计算和分析.但多数情况下,这些端口并不是纯电阻的特性,更精确一些,它可能是电阻电容以及电感的组合,表现为 ...
- 聊聊Seata分布式解决方案AT模式的实现原理
什么是Seata分布式事务解决方案 Seata是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.为用户提供了AT.TCC.SAGA和XA事务模式,为用户打造一站式的分布式解决 ...
- proto中service 作用的理解
转载请注明出处: 在 proto 文件中,service 用于定义一组 RPC 方法,在服务端实现这些方法,并在客户端调用这些方法进行远程过程调用. service 的定义方式如下: service ...
- 使用js闭包封装一个原生的模态框
现在都是用的是人家封装的框架什么的,但是对于底层的了解也是必须的,不然就无法提升,下面分享一个2 years ago 自己封装的一个提示框 样式很简单(适用于任何分辨率) 具体代码如下 /** * 该 ...
- Linux之从进程角度来理解文件描述符
文件描述符是一个非负整数,而内核需要通过这个文件描述符才可以访问文件.当我们在系统中打开已有的文件或新建文件时,内核每次都会给特定的进程返回一个文件描述符,当进程需要对文件进行读或写操作时,都要依赖这 ...
- odoo开发教程四:onchange、唯一性约束
一:onchange机制[onchange=前端js函数!可以实现前端实时更新以及修改验证] onchange机制:不需要保存数据到数据库就可以实时更新用户界面上的显示. @api.onchange( ...
- error: #20: identifier "arm_cfft_instance_f64" is undefined
在使用Keil5的过程中,偶尔遇到这个问题,以及类似的问题,报错的数量大概200多个. error type>(42): error: #20: identifier "arm_cff ...