dp(过河问题)
http://codeforces.com/gym/101492/problem/E
思路:
按过河时间排序后
有两种最优策略:
1.最轻的带最重的过去,
2.两个最轻的带两个最重的过去。
每次判断两人,比较两种策略哪个更优。
样例1:编号为1,2,3,首先1和3先过去,1回来,然后1和2过去,时间是50+30+40=120
样例2:编号为1,2,3,4,首先1和2先过去,1回来,然后3和4过去,2回来,最后1和2过去,时间是20+10+100+20+20=170
题目分析:这题看起来似乎是dp的题目,但是看内存和时间,2个循环的时间并不足够。但是稍微分析,其实可以发现,有两种情况:
假设有编号为1,2,3,4,4个人在A要去B;
第一种情况:先1+2过去,然后换3+4过去;具体流程是1+2过去,1回来,3+4过去,2回来,此时时间是t1=num[2]+num[1]+num[4]+num[2]=num[2]*2+num[1]+num[4];
第二种情况:1+4过去,1回来,1+3过去,1回来;也就是通过1来回,逐个过去。时间是t2=num[4]+num[1]+num[3]+num[1]=num[1]*2+num[3]+num[4];
由上两种情况,总结出选择哪一种过法,可以比较t1和t2的时间取小,也就是看num[2]+num[2]>num[1]+num[3]?t1:t2
#include <cmath>
#include <algorithm>
#include <iostream>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <stdio.h>
#include <set>
#include <stack>
#include <string.h>
#include <vector>
#include <queue>
#define ME(x , y) memset(x , y , sizeof(x))
#define SF(n) scanf("%d" , &n)
#define rep(i , n) for(int i = 0 ; i < n ; i ++)
#define INF 0x3f3f3f3f
using namespace std;
long long a[]; int main()
{
int n ;
while(scanf("%d" , &n) != EOF)
{
for(int i = ; i < n ; i++)
{
scanf("%lld" , &a[i]);
}
sort(a , a + n);
long long ans = ;
if(n == )
{
ans = a[];
}
else
{
if(n % == )
{
ans += a[] + a[] + a[];
for(int i = ; i < n ; i += )
{
ans += min( *a[] + a[i-] + a[i] , a[] + *a[] + a[i]);
}
}
else
{
ans += a[];
for(int i = ; i < n ; i += )
{
ans += min(*a[] + a[i-] + a[i] , a[] + *a[] + a[i]);
}
}
}
printf("%lld\n" , ans); } return ;
}
http://poj.org/problem?id=2573
另外需要输出具体过程
//#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <string>
#include <stdio.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <string.h>
#include <vector>
#define ME(x , y) memset(x , y , sizeof(x))
#define SF(n) scanf("%d" , &n)
#define rep(i , n) for(int i = 0 ; i < n ; i ++)
#define INF 0x3f3f3f3f
#define mod 20191117
#define PI acos(-1)
using namespace std;
typedef long long ll ;
int a[1009]; vector<int>v[100009];
int main()
{
int n ;
scanf("%d" , &n);
for(int i = 1 ; i <= n ; i++)
{
scanf("%d" , &a[i]);
}
if(n == 1){
cout << a[1] << endl;
cout << a[1] << endl;
return 0 ;
}
sort(a + 1 , a + n + 1);
int ans = 0 , j , sum = 0;
for(j = n ; j >= 4 ; j -= 2)
{
if(a[j]+a[j-1]+2*a[1] >= a[j]+a[1]+2*a[2])
{
sum += a[j]+a[1]+2*a[2] ;
v[++ans].push_back(a[1]),v[ans].push_back(a[2]);
v[++ans].push_back(a[1]);
v[++ans].push_back(a[j-1]), v[ans].push_back(a[j]);
v[++ans].push_back(a[2]);
}
else{
sum += a[j]+a[j-1]+2*a[1] ;
v[++ans].push_back(a[1]) , v[ans].push_back(a[j]);
v[++ans].push_back(a[1]);
v[++ans].push_back(a[1]), v[ans].push_back(a[j-1]);
v[++ans].push_back(a[1]);
}
}
if(j == 2)
{
sum += a[2] ;
v[++ans].push_back(a[1]) , v[ans].push_back(a[2]);
}
else{
sum += a[1] + a[2] + a[3];
v[++ans].push_back(a[1]) , v[ans].push_back(a[3]);
v[++ans].push_back(a[1]);
v[++ans].push_back(a[1]) , v[ans].push_back(a[2]);
}
cout << sum << endl ;
for(int i = 1 ; i <= ans ; i++)
{
if(v[i].size() == 2)
{
cout << v[i][0] << " " << v[i][1] << endl;
}
else{
cout << v[i][0] << endl ;
}
}
return 0;
}
dp(过河问题)的更多相关文章
- DP 过河卒
棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为“马拦过河卒”. 棋盘用坐标 ...
- 袋鼠过河---DP
题目:一只袋鼠要从河这边跳到河对岸,河很宽,但是河中间打了很多桩子,每隔一米就有一个,每个桩子上都有一个弹簧,袋鼠跳到弹簧上就可以跳的更远,每个弹簧力量不同,用一个数字代表它的力量,如果弹簧力量为5, ...
- NOIP2005过河[DP 状态压缩]
题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数 ...
- ooj 1066 青蛙过河DP
http://121.249.217.157/JudgeOnline/problem.php?id=1066 1066: 青蛙过河 时间限制: 1 Sec 内存限制: 64 MB提交: 58 解决 ...
- Vijos p1002 过河 离散化距离+区间DP
链接:https://vijos.org/p/1002 题意:一条长度为L(L <= 1e9)的桥上有N(1<= N <= 100)颗石头.桥的起点为0终点为L.一只青蛙从0开始跳, ...
- [HDU 4842]--过河(dp+状态压缩)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4842 过河 Time Limit: 3000/1000 MS (Java/Others) Mem ...
- Vijos 1002 过河 状态压缩DP
描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上 ...
- P1052 过河 线性dp 路径压缩
题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数 ...
- P1052 过河 线性dp
题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数 ...
- [Alg::DP] 袋鼠过河
一道简单的动态规划问题. 题目来源:牛客网 链接:https://www.nowcoder.com/questionTerminal/74acf832651e45bd9e059c59bc6e1cbf ...
随机推荐
- C#/.NET VS2017+ EF+SQLite.CodeFirst——真正实现CodeFirst
本文所介绍的是真正的EF+CodeFirst,不需要提前建表,由代码自动生成! 进行前需要准备的: 1.下载Sqlite Experthttp://www.sqliteexpert.com/downl ...
- Rsync+sersync 数据同步指南
(1):sersync 可以记录下被监听目录中发生变化的(包括增加.删除.修改)具体某一个文件或 某一个目录的名字: (2):rsync 在同步的时候,只同步发生变化的这个文件或者这个目录(每次发生变 ...
- PHP Session 序列化及反序列化处理器设置使用不当带来的安全隐患(转)
PHP Session 序列化及反序列化处理器设置使用不当带来的安全隐患 时间 2014-11-14 15:05:49 WooYun知识库 原文 http://drops.wooyun.org/t ...
- jquery 模态对话框传值,删除,新增表格行
个人的练习代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- j函数 判断以 什么开头
1.str.charAt(index) 返回字符串中指定位置的字符. str 是字符串 我们要将获得的数据 转化为字符串 var code = res.statusCode.toString(); ...
- 【串线篇】spring boot页面模板引擎
如JSP.Velocity.Freemarker.Thymeleaf SpringBoot推荐的Thymeleaf:语法更简单,功能更强大: 一.引入thymeleaf <dependency& ...
- div+css做出带三角的弹出框 和箭头
一.三角形 https://blog.csdn.net/Szu_AKer/article/details/51755821 notice:三角的那部分可以用图片作为背景,但是容易出现杂边.所以利用cs ...
- 线程中sleep和wait方法的区别
sleep() 方法: 线程主动放弃CPU,使得线程在指定的时间内进入阻塞状态,不能得到CPU 时间,指定的时间一过,线程重新进入可执行状态.典型地,sleep()被用在等待某个资源就绪的情形:测试发 ...
- UVa 10054 : The Necklace 【欧拉回路】
题目链接 题目大意:我的妹妹有一串由各种颜色组成的项链. 项链中两个连续珠子的接头处共享同一个颜色. 如上图, 第一个珠子是green+red, 那么接这个珠子的必须以red开头,如图的red+whi ...
- Linux Crontab命令定时任务基本语法
一.Crontab查看编辑重启 1.查看crontab定时执行任务列表 crontab -l 2.编辑crontab定时执行任务 crontab -e 3.删除crontab定时任务 crontab ...