Problem Statement | |||||||||||||
A well-known riddle goes like this: Four people are crossing an old bridge. The bridge cannot hold more than two people at once. It is dark, so they can't walk without a flashlight, and they only have one flashlight! Furthermore, the time needed to cross the bridge varies among the people in the group. For instance, let's say that the people take 1, 2, 5 and 10 minutes to cross the bridge. When people walk together, they always walk at the speed of the slowest person. It is impossible to toss the flashlight across the bridge, so one person always has to go back with the flashlight to the others. What is the minimum amount of time needed to get all the people across the bridge? In this instance, the answer is 17. Person number 1 and 2 cross the bridge together, spending 2 minutes. Then person 1 goes back with the flashlight, spending an additional one minute. Then person 3 and 4 cross the bridge together, spending 10 minutes. Person 2 goes back with the flashlight (2 min), and person 1 and 2 cross the bridge together (2 min). This yields a total of 2+1+10+2+2 = 17 minutes spent. You want to create a computer program to help you solve new instances of this problem. Given an vector <int>times, where the elements represent the time each person spends on a crossing, your program should return the minimum possible amount of time spent crossing the bridge. | |||||||||||||
Definition | |||||||||||||
| |||||||||||||
Limits | |||||||||||||
| |||||||||||||
Notes | |||||||||||||
- | In an optimal solution, exactly two people will be sent across the bridge with the flashlight each time (if possible), and exactly one person will be sent back with the flashlight each time. In other words, in an optimal solution, you will never send more than one person back from the far side at a time, and you will never send less than two people across to the far side each time (when possible). | ||||||||||||
Constraints | |||||||||||||
- | times will have between 1 and 6 elements, inclusive. | ||||||||||||
- | Each element of times will be between 1 and 100, inclusive. | ||||||||||||
Examples | |||||||||||||
0) | |||||||||||||
| |||||||||||||
1) | |||||||||||||
| |||||||||||||
2) | |||||||||||||
| |||||||||||||
3) | |||||||||||||
|
很经典的一个过桥问题
之前在思维训练题目中还见到过一样的题,没想到直接成为了一道tc题= =
当时还想了很久呢,现在才发现,首先不能贪心,任何直接贪心做出来的都基本上会wrong的,不信你去试试(=。=!)。
反正数据范围是6,就用dfs搜索办法,最关键的地方是,每次从对岸选取一个人返回的时候,都要选取过桥时间最少的那个!并且注意最后一趟,2个人过去了后,就不需要返回了.
这里的dfs不是很好写,反反复复弄了好久才弄出来,建议不要看我代码,还是自己写出来比较好,毕竟我写的有点乱。
//Hello. I'm Peter.
#include<cstdio>
#include<iostream>
#include<sstream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<cctype>
#include<ctime>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double ld;
#define peter cout<<"i am peter"<<endl
#define input freopen("data.txt","r",stdin)
#define randin srand((unsigned int)time(NULL))
#define INT (0x3f3f3f3f)*2
#define LL (0x3f3f3f3f3f3f3f3f)*2
#define gsize(a) (int)a.size()
#define len(a) (int)strlen(a)
#define slen(s) (int)s.length()
#define pb(a) push_back(a)
#define clr(a) memset(a,0,sizeof(a))
#define clr_minus1(a) memset(a,-1,sizeof(a))
#define clr_INT(a) memset(a,INT,sizeof(a))
#define clr_true(a) memset(a,true,sizeof(a))
#define clr_false(a) memset(a,false,sizeof(a))
#define clr_queue(q) while(!q.empty()) q.pop()
#define clr_stack(s) while(!s.empty()) s.pop()
#define rep(i, a, b) for (int i = a; i < b; i++)
#define dep(i, a, b) for (int i = a; i > b; i--)
#define repin(i, a, b) for (int i = a; i <= b; i++)
#define depin(i, a, b) for (int i = a; i >= b; i--)
#define pi 3.1415926535898
#define eps 1e-6
#define MOD 1000000007
#define MAXN 100100
#define N
#define M 200
int ans;
struct Digit
{
int id;
int times;
}d,d1,d2,back;
Digit chooseone(vector<Digit>there)
{
int len=gsize(there);
int mini=INT;
Digit res;
rep(i,0,len)
{
if(mini>there[i].times)
{
mini=there[i].times;
res=there[i];
}
}
return res;
}
void dfs(vector<Digit>here,vector<Digit>there,int totaltime)
{
int len1=gsize(here);
if(len1<=2)
{
totaltime+=max(here[0].times,here[1].times);
ans=min(ans,totaltime);
return;
}
int newtotaltime;
rep(i,0,len1)
{
rep(j,i+1,len1)
{
d1=here[i];
d2=here[j];
newtotaltime=totaltime;
newtotaltime+=max(d1.times,d2.times);
vector<Digit>newtheretemp;
newtheretemp.clear();
int len2=gsize(there);
rep(k,0,len2)
{
d=there[k];
newtheretemp.pb(d);
}
newtheretemp.pb(d1);
newtheretemp.pb(d2);
back=chooseone(newtheretemp);
newtotaltime+=back.times;
vector<Digit>newthere;
newthere.clear();
len2=gsize(newtheretemp);
rep(k,0,len2)
{
d=newtheretemp[k];
if(d.id!=back.id) newthere.pb(d);
}
//for here
vector<Digit>newhere;
newhere.clear();
rep(k,0,len1)
{
d=here[k];
if(d.id!=d1.id && d.id!=d2.id) newhere.pb(d);
}
newhere.pb(back);
dfs(newhere,newthere,newtotaltime);
}
}
}
class BridgeCrossing
{
public:
int minTime(vector <int> times)
{
ans=INT;
int len=gsize(times);
if(len==1)
{
ans=min(ans,times[0]);
}
else
{
vector<Digit>there;
there.clear();
vector<Digit>here;
rep(i,0,len)
{
d.id=i;
d.times=times[i];
here.pb(d);
}
dfs(here,there,0);
}
return ans;
}
};