寒假集训02 J hdu 5303 DP+枚举
2016-01-14 17:17
447 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5303
题意:
在一圈长为l的圆圈周围种了n棵苹果树
有一个容积为k的篮子
圆圈的原点是0,顺时针方向记录了苹果树的位置以及苹果的数量
将苹果全部摘完,最少需要走多少路
篮子装满就必须走回原点
题目分析:
对这个环,有3种操作:
1.顺时针过去取
2.逆时针过去取
3.绕这个环一圈取
1和2如果走过了环的一半,就变成了3,所以1和2是不能走过环的一半的。
而对于1和2,每次取的k个苹果,其花费的距离必然为max(xi)*2|i=1,2...k,所以拿的这k个苹果的距离一定是当前这半环中的最大的k个,因为既然花费距离已定,那不如将这次操作的优化价值提升到最大,也就是每次都尽量消去距离最远的苹果。
对于3,同样,花费一定是L,每次也同样要消去距离最远的苹果。但是,可以发现,如果操作中出现了2次操作3,那么这个操作一定不是最优的,因为可以通过1和2两次操作取得两次操作3获得的苹果,且花费更低。所以操作中只可能出现一次操作3且这次操作3若要发生,一定发生在操作刚开始,因为此时进行操作3的优化价值是最大的。
综上得到以下解法:
1、先分左边和右边分别进行DP,求出最少距离。设dpl[i],dpr[i]分别表示采摘左边、右边的第i个苹果时的最少距离总和。
2、枚举走一圈情况下的左边和右边的苹果数量,得到距离和上面比较,取最小值。
注意点:
取值范围取long long, 输入最好用scanf()
#include <iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
using namespace std;
#define N 100005
#define ll long long
int l
, r
;
ll dpl
, dpr
;
int main()
{
//freopen("E:\input.txt", "r", stdin);
int t;
int L, n, k;
int i;
int n1, n2;
ll sum;
cin >> t;
while (t--)
{
memset(l, 0, sizeof(l));
memset(r, 0, sizeof(r));
memset(dpl, 0, sizeof(dpl));
memset(dpr, 0, sizeof(dpr));
n1 = 0;
n2 = 0;
sum = 0;
int x, a;
cin >> L >> n >> k;
//scanf("%d%d%d", &L, &n, &k);
for (i = 0; i < n; i++)
{
//cin >> x >> a;
scanf("%d%d", &x, &a);
while (a--)
{
if (2 * x > L)
{
l[++n1] = L - x;
}
else
{
r[++n2] = x;
}
}
}
sort(l + 1, l + n1 + 1);
sort(r + 1, r + n2 + 1);
//sort(x, x + n);
dpl[0] = 0;
dpr[0] = 0;
for (i = 1; i <= n1; i++)
{
if (i <= k)
{
dpl[i] = l[i];
}
else
{
dpl[i] = dpl[i - k] + l[i];
}
}
for (i = 1; i <= n2; i++)
{
if (i <= k)
{
dpr[i] = r[i];
}
else
{
dpr[i] = dpr[i - k] + r[i];
}
}
sum = 2 * (dpl[n1] + dpr[n2]);
for (i = 0; i <= min(n1, k); i++) //枚举走一圈时左边苹果的数量
{
//k-i为走一圈时右边苹果的数量,n2-(k-i)就是右边原路返回采摘的苹果数量
int j = max(n2 - (k - i), 0);
////最后的结果就是左边原路返回方案的花费加上右边原路返回的花费,再加上圈长
sum = min(sum, 2 * (dpl[n1 - i] + dpr[j]) + L);
}
// cout << sum << endl;
printf("%I64d\n", sum);
}
return 0;
}
hdu 5303 相关1
HDU 5303 相关2
题意:
在一圈长为l的圆圈周围种了n棵苹果树
有一个容积为k的篮子
圆圈的原点是0,顺时针方向记录了苹果树的位置以及苹果的数量
将苹果全部摘完,最少需要走多少路
篮子装满就必须走回原点
题目分析:
对这个环,有3种操作:
1.顺时针过去取
2.逆时针过去取
3.绕这个环一圈取
1和2如果走过了环的一半,就变成了3,所以1和2是不能走过环的一半的。
而对于1和2,每次取的k个苹果,其花费的距离必然为max(xi)*2|i=1,2...k,所以拿的这k个苹果的距离一定是当前这半环中的最大的k个,因为既然花费距离已定,那不如将这次操作的优化价值提升到最大,也就是每次都尽量消去距离最远的苹果。
对于3,同样,花费一定是L,每次也同样要消去距离最远的苹果。但是,可以发现,如果操作中出现了2次操作3,那么这个操作一定不是最优的,因为可以通过1和2两次操作取得两次操作3获得的苹果,且花费更低。所以操作中只可能出现一次操作3且这次操作3若要发生,一定发生在操作刚开始,因为此时进行操作3的优化价值是最大的。
综上得到以下解法:
1、先分左边和右边分别进行DP,求出最少距离。设dpl[i],dpr[i]分别表示采摘左边、右边的第i个苹果时的最少距离总和。
2、枚举走一圈情况下的左边和右边的苹果数量,得到距离和上面比较,取最小值。
注意点:
取值范围取long long, 输入最好用scanf()
#include <iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
using namespace std;
#define N 100005
#define ll long long
int l
, r
;
ll dpl
, dpr
;
int main()
{
//freopen("E:\input.txt", "r", stdin);
int t;
int L, n, k;
int i;
int n1, n2;
ll sum;
cin >> t;
while (t--)
{
memset(l, 0, sizeof(l));
memset(r, 0, sizeof(r));
memset(dpl, 0, sizeof(dpl));
memset(dpr, 0, sizeof(dpr));
n1 = 0;
n2 = 0;
sum = 0;
int x, a;
cin >> L >> n >> k;
//scanf("%d%d%d", &L, &n, &k);
for (i = 0; i < n; i++)
{
//cin >> x >> a;
scanf("%d%d", &x, &a);
while (a--)
{
if (2 * x > L)
{
l[++n1] = L - x;
}
else
{
r[++n2] = x;
}
}
}
sort(l + 1, l + n1 + 1);
sort(r + 1, r + n2 + 1);
//sort(x, x + n);
dpl[0] = 0;
dpr[0] = 0;
for (i = 1; i <= n1; i++)
{
if (i <= k)
{
dpl[i] = l[i];
}
else
{
dpl[i] = dpl[i - k] + l[i];
}
}
for (i = 1; i <= n2; i++)
{
if (i <= k)
{
dpr[i] = r[i];
}
else
{
dpr[i] = dpr[i - k] + r[i];
}
}
sum = 2 * (dpl[n1] + dpr[n2]);
for (i = 0; i <= min(n1, k); i++) //枚举走一圈时左边苹果的数量
{
//k-i为走一圈时右边苹果的数量,n2-(k-i)就是右边原路返回采摘的苹果数量
int j = max(n2 - (k - i), 0);
////最后的结果就是左边原路返回方案的花费加上右边原路返回的花费,再加上圈长
sum = min(sum, 2 * (dpl[n1 - i] + dpr[j]) + L);
}
// cout << sum << endl;
printf("%I64d\n", sum);
}
return 0;
}
hdu 5303 相关1
HDU 5303 相关2
相关文章推荐
- iostat--磁盘IO性能监控
- 学习JavaScript设计模式之中介者模式
- 百度低调推出百度媒体号
- DarunGrim3安装使用说明
- 【HttpClient4.5中文教程】其他章节及总结
- Ichars制作数据统计图
- treap 1286郁闷的出纳员.cpp
- 创建型模式5之4-Builder建造者模式例子理解
- 1安全基线远程评估系统
- C++引用
- css 常用总结
- fgets()重复读取最后一行的分析及解决方法
- 学数据结构与算法推荐的书
- sql语句优化SQL Server
- 【codeforces 333A】 - Secrets
- 程序员小白的这一年
- arcmap json转feacture
- json转换成list map集合
- KISSY 库 demo
- 读《编写可维护的JavaScript》第六章总结