WOJ 1538 Stones II 转化背包问题
昨天是我负责这个题目的,最后没搞出来,真的给队伍拖后腿了。
当时都推出来了 我假设最后结果是取了m个物品,则我把这个m个物品按取的先后编号为 k1 k2 k3 k4...km
则最终结果就是 (k1.a+k2.a+...km.a)-((m-1)*k1.b+(m-2)*k2.b+....+1*k(m-1).b+0*km.b);
由此可见最终的结果必定是从n个石头中选出m个石头,而且这m个石头要按b值的升序来取,因为按上述式子,这m个石头的a值顺序不影响结果,但b值越小的放前面就使得结果越优,这里也算用了一下贪心思想吧,不过是显而易见的。
然后当时聪哥就照着这个敲了一个贪心的,WA了。。。之后就肯定了绝对不仅仅用贪心来解
然后一直到比赛结束,我都没想到合适的方法来解。。。
其实已经给定了取的顺序,在n个物品中取m件使得价值最大。。。这不就是典型的背包问题嘛。。。哎,我真的是觉得自己当时脑袋短路的可以
于是我们定义一个d[i][j],表示当前第i件物品放到j位置的最大值(当然该件物品也可以不取,但这个状态必须保留下来)。
于是我们把b值按降序排序。从后往前来取石头比较好算一点。
d[i][j]=max(d[i-1][j],d[i-1][j-1]+ai-(j-1)*bi)
d[i-1][j]就代表当前这个物品我不取,后面那个就代表取,但是我就有点纠结这个(j-1)*bi这里,因为我背包过程中,d[i][j]虽然是规定了i件物品在在第j次取,但是之前也存在不取的情况,那此时这个石头还是第j次取吗?后来我发现自己想多了,首先按我的定义这个式子是肯定没错的,其次,如果结果最终是存在一个取石头的序列,那么必定就能通过这个式子来得到结果。。否则就是0了。就是把i件物品在各个位置的值都求一下,最后总结起来就存在那样的放置方法即可。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 1010
using namespace std;
int d[N][N];
struct node
{
int a,b;
bool operator <(const node &rhs) const
{
if (b==rhs.b)
return a>rhs.a;
return b>rhs.b;
}
} s[N];
int main()
{
int n;
while (scanf("%d",&n) && n)
{
for (int i=;i<=n;i++)
scanf("%d%d",&s[i].a,&s[i].b);
sort(s+,s++n);
memset(d,,sizeof d);
for (int i=;i<=n;i++)
{
for (int j=;j<=i;j++)
{
d[i][j]=max(d[i-][j],d[i-][j-]+s[i].a-(j-)*s[i].b);
}
}
int ans=;
for (int i=;i<=n;i++)
ans=max(ans,d[n][i]);
printf("%d\n",ans);
}
return ;
}
WOJ 1538 Stones II 转化背包问题的更多相关文章
- WHU 1538 Stones II 动态规划
赛后写的,动态规划,学长和题解,提供了两种状态设计的思路,都写了下……结果在写第二种的时候,不小心把下标的起点写错了,导致WA了无数发…… 无奈啊……每次都是这种错误…… 题意: 大概就是有n块石头, ...
- WOJ 1538 B - Stones II
Problem 1538 - B - Stones IITime Limit: 1000MS Memory Limit: 65536KB Total Submit: 416 Accepted: 63 ...
- whu 1538 - B - Stones II 01背包
题目链接: http://acm.whu.edu.cn/land/problem/detail?problem_id=1538 Problem 1538 - B - Stones II Time Li ...
- Problem 1538 - B - Stones II 贪心+DP
还是给你石头n枚,每一枚石头有两个值a和b,每取一个石头,除了这块石头其余所有的石头的a就都减去这个石头的b,问你取了的石头的a的总和最大可以为多少? 先按B从大到小排序 然后DP: 取的话:dp[i ...
- UVa 11426 - GCD - Extreme (II) 转化+筛法生成欧拉函数表
<训练指南>p.125 设f[n] = gcd(1, n) + gcd(2, n) + …… + gcd(n - 1, n); 则所求答案为S[n] = f[2]+f[3]+……+f[n] ...
- 【转载】ACM总结——dp专辑
感谢博主—— http://blog.csdn.net/cc_again?viewmode=list ---------- Accagain 2014年5月15日 动态规划一 ...
- 【DP专辑】ACM动态规划总结
转载请注明出处,谢谢. http://blog.csdn.net/cc_again?viewmode=list ---------- Accagain 2014年5月15日 ...
- dp专题训练
****************************************************************************************** 动态规划 专题训练 ...
- 【DP专辑】ACM动态规划总结(转)
http://blog.csdn.net/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码量少,多元性强, ...
随机推荐
- 使用线程池测试cpu的并发计算能力
接到一个需求是测试一下cpu并发计算能力,针对int和float求和单位时间能执行几次的问题.可能是服务器选型用到的参数. 开始使用的是fork-join,但是发现fork-join每次得到的结果值波 ...
- YOKOGAWA ProSafe-RS 通道测试 CENTUMVP
20180927 我并没有调试这个项目 仅仅是听同事讲解了 横河ProSafe-RS通道测试 然后做了笔记 软件安装并不在本记录中 ProSafe-RS版本 CENTUMVP版本 ProSafe-RS ...
- NIO 与 零拷贝
零拷贝介绍 零拷贝是网络编程的关键, 很多性能优化都需要零拷贝. 在 Java程序中, 常用的零拷贝方式有m(memory)map[内存映射] 和 sendFile.它们在OS中又是怎样的设计? NI ...
- mysql数据库可视化工具—Navicat Premium—安装与激活
一.Navicat premium简介 Navicat premium是一款数据库管理工具.将此工具连接数据库,你可以从中看到各种数据库的详细信息.包括报错,等等.当然,你也可以通过他,登陆数据库,进 ...
- linux 查看运行进程详细信息
Linux在启动一个进程时,系统会在/proc下创建一个以PID命名的文件夹,在该文件夹下会有我们的进程的信息 通过ll或ls –l命令即可查看. ll /proc/PID cwd符号链接的是进程运行 ...
- Window Server 2019 配置篇(3)- 建立hyper-v集群并在其上运行win10 pro虚拟机
上次讲到我们的域里有了网关跟DHCP,这次我们要在域中建立hyper-v集群并在其上运行win10 pro虚拟机 那么什么是hyper-v集群呢? 就是两个及两个以上的运行hyper-v服务的服务器建 ...
- TX2开发板Ubuntu16.04设置静态IP
TX2开发板Ubuntu16.04设置静态IP https://www.cnblogs.com/qilai/p/11285445.html 首先打开一个Terminal输入 ifconfig 查看自 ...
- 119-PHP调用private成员的方法
<?php class ren{ //定义人类 private $birthday='1990-12-20'; //定义private修饰的成员属性 public function say_bi ...
- 107-PHP类成员属性赋值
<?php class mao{ //定义猫类 public $age; //定义多个成员属性 protected $weight; private $color; } $mao1=new ma ...
- jQuery获取display为none的隐藏元素的宽度和高度的解决方案
1.利用给元素添加行内样式:visibility:hidden;display:block 2.让隐藏元素变成有物理尺寸存在,但不可见,获取元素宽高 3.再给它还原成display为none,去除vi ...