Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 1737 | Accepted: 616 |
Description
You have N stones (1 ≤ N ≤ 10), each stone is characterized by weight pi and cost vi (i = 1, ... , N). You should drop these stones by a gutter into one of the two bunkers: A or В.
The mechanism of receiving bunkers switching works as follows. The stones are dropping into one of the bunkers until the weight of this bunker’s content will exceed the weight of stones in other bunker by more than D. Then the gutter switches to the other bunker. At the beginning both bunkers are empty, and the first stone falls into the bunker А.
The task is to collect stones with maximum total cost in bunker B after all stones have been dropped.
Input
The input consists of N + 1 lines. The first line contains values N and D separated by one or several spaces. The next lines contain values pi and vi, also separated by spaces. All input data (except N) are integers from 0 to 10000.
Output
The output contains a single line with total cost of stones in the bunker B.
Sample Input
4 2 2 2 2 2 1 1 1 1
Sample Output
3
开始没加优化 本来10^10 的复杂度跑出来是1800ms,
加了判断A水沟花费总值得判断后, 快了很多,只用了300ms.
有个同学用的是 next_permutation函数,把所有排列都试了一遍,复杂度应该是10!*10, 跑出来是1200ms .
有两秒时间, 数据又比较水,所以这题可以比较轻松地用搜索过掉.
题意是有n个石头,每个石头有对应的重量pi, 和对应的 价值 vi;
有两条水沟,, 轮流放石头, 要求B水沟最后的总花费要最大. 每次放可以放任意哪个石头.
开始是在A水沟里放, A的总重量大于 B 水沟重量+D后, 就开始放石头进B , 如果B水沟总重量大于 A水沟总重量+D,下一次又开始要放石头进A水沟
优化的地方,就是每次搜索完一边 , 就把 计算一下 A水沟的总花费的最小值, 如果下一次搜索过程中,A水沟花费大于或等于 A水沟之前计算出的最小值,显然后面的再搜索下去也是没意义的, 就直接return 掉;
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int maxx;
int a[20][5];
int n,d;
int vis[20],zong;
int tem[20];
int sum;
int maa(int a,int b)
{
return a>b?a:b;
}
int mii(int a,int b)
{
return a<b?a:b;
}
int aans;
void dfs(int num,int diji,int sum1,int sum2,int cost,int cost2)
{
if(aans<cost2)//优化的地方,,aans 是A水沟 跑出来的 最小值. 如果花费超过他 显然不行.
{
return;
}
if(num==n)
{////
maxx=maa(cost,maxx);
aans=min(aans,sum-cost);
return;
}
for(int i=0;i<n;i++)
{
if(vis[i]==0)
{
vis[i]=1;
if(diji==1&&sum1+a[i][0]-sum2>d)
{
dfs(num+1,2,sum1+a[i][0],sum2,cost,cost2+a[i][1]);
}
else if(diji==2&&sum2+a[i][0]-sum1>d)
{
dfs(num+1,1,sum1,sum2+a[i][0],cost+a[i][1],cost2);
}
else
{
if(diji==2)
{
dfs(num+1,2,sum1,sum2+a[i][0],cost+a[i][1],cost2);
}
else
dfs(num+1,1,sum1+a[i][0],sum2,cost,cost2+a[i][1]);
}
vis[i]=0;
}
}
return ;
}
int main()
{
int i;
scanf("%d%d",&n,&d);
maxx=0;
sum=0;
aans=1000000000;
for(i=0;i<n;i++)
{
scanf("%d%d",&a[i][0],&a[i][1]);//[0]是 p [1]是cost v
sum+=a[i][1];
}
memset(vis,0,sizeof(vis));
dfs(0,1,0,0,0,0);
printf("%d\n",maxx);
return 0;
}