超大背包问题
2018-03-06 18:57
169 查看
文章用的C++ 我想着用C语言实现# include <stdio.h>
# define N 40
# define max(a,b) (a)>(b)?(a):(b)
# define M 1<<(N>>1)
typedef long long LL;
void change(LL *a,LL *b);
void Qsort(LL A[][M],LL left,LL right);//快速排序升序
int search(LL A[],int n,LL key);//查找 A中 的key 病返回 key所在的价值最大值
LL W
,V
,C[2][M];
int main(){
int n,i,j,k,m;
LL w,sum,sw,sv,num,tv;
// freopen("AAA.txt","r",stdin);
while(~scanf("%d",&n))
{
for(i=0;i<n;i++)
scanf("%lld%lld",&W[i],&V[i]);
scanf("%lld",&w);//录入
k=n/2;m=1<<k;
for(i=0;i<m;i++)
{
C[0][i]=C[1][i]=0;//初始化
for(j=0;j<k;j++)
if(i>>j&1)
{
C[0][i]+=W[j];//枚举前半部分
C[1][i]+=V[j];
}
}
Qsort(C,0,m-1);//字典序——升序
for(j=0,i=1;i<m;i++)
{
if(C[1][j]<C[1][i])
{
C[0][j]=C[0][i];
C[1][j++]=C[1][i];//去掉多余元素
}
}
num=j;
for(sum=0,i=0,m=(n-k),n=1<<m;i<n;i++)//枚举后半部分 并求解
{
sw=sv=0;
for(j=0;j<m;j++)
{
if(i>>j&1)
{
sw+=W[k+j];
sv+=V[k+j];
}
}
if(sw<=w)
{
tv=search(C[0],num,w-sw);
sum=max(sum,sv+tv);
}
}
printf("%lld\n",sum);
}
return 0;
}
void change(LL *a,LL *b){//交换函数
LL c=*a;
*a=*b;
*b=c;
}
void Qsort(LL A[][M],LL left,LL right)//快速排序升序
{
LL i=left,j=right,temp[2]={A[0][left],A[1][left]};
if(left>=right) return;
while(i!=j)
{
while((A[0][j]>temp[0]||A[0][j]==temp[0]&&A[1][j]>=temp[1])&& i<j)j--;
while((A[0][i]<temp[0]||A[0][i]==temp[0]&&A[1][i]<=temp[1])&& i<j)i++;
if(i<j)
{
change(&A[0][i],&A[0][j]);
change(&A[1][i],&A[1][j]);
}
}
if(i!=left)
{
change(&A[0][left],&A[0][i]);
change(&A[1][left],&A[1][i]);
}
Qsort(A,left,i-1);
Qsort(A,i+1,right);
}
int search(LL A[],int n,LL key)
{
int L=0,R=n-1,mid,num=0;
while(L<=R)
{
mid=(L+R)>>1;
if(A[mid]==key) {
while(mid<n&&A[++mid]==key);
return C[1][mid-1];
}
else if(A[mid]>key)
R=mid-1;
else L=mid+1;
}
return 0;
}
相关文章推荐
- CSU OJ PID=1514: Packs 超大背包问题,折半枚举+二分查找。
- 超大背包问题(枚举二分)
- 《挑战程序设计竞赛中》所讲的超大背包问题
- 超大背包问题(折半枚举)
- 超大背包问题 折半枚举
- 超大背包问题 (折半枚举)
- 中途相遇法 解决 超大背包问题 pack
- 超大背包问题
- 超大背包问题
- 超大背包问题
- ZOJ 3631超大背包问题(DFS || 折半搜索)
- codeforces808E(超大背包的解决问题,中途相遇法)
- acm常用技巧四 超大背包问题
- 超大背包问题
- 超大背包问题
- 挑战 超大背包问题
- 超大背包问题 折半枚举法
- 《挑战程序设计竞赛》 超大背包问题实现
- 超大背包问题 (折半枚举)
- 162_超大背包问题 (双向搜索)