hdu 3017 Treasure Division 折半枚举 + 双指针
来源:互联网 发布:淘宝手机详情页装修 编辑:程序博客网 时间:2024/05/23 13:55
运气不错排了第二。内存比他们大了好多。不知道他们是什么方法。
把n个coin分成两半,在两半里分别枚举所有情况,第一半取了i枚硬币则把价值存入s1[i],第二半取了i枚硬币则把价值存入s2[i]。时间复杂度2 × 2^(n/2 ) 。然后都排序。
假设所有硬币总价值为sum,aim = sum/2.
最后要把硬币都分成两部分,我们只求价值小的那部分。所以这个要求的 一定小于等于aim,并且越大越优
枚举s1中的所有情况,在s2中找对应最优的,用双指针
#pragma comment(linker, "/STACK:102400000,102400000")#include<stdio.h>#include<string.h>#include<ctype.h>#include<math.h>#include<string>#include<vector>#include<map>#include<queue>#include<set>#include<algorithm>using namespace std;void fre(){freopen("t.txt","r",stdin);}#define ls o<<1#define rs o<<1|1#define MS(x,y) memset(x,y,sizeof(x))#define MC(x,y) memcpy(x,y,sizeof(y))template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }typedef long long LL;typedef unsigned long long UL;typedef unsigned int UI;const int INF = 0x3f3f3f3f ;const double pi = acos(-1.0);const int MAXN = 100010;const LL M = 20090818;int n,mid,c1[16],c2[16];;LL a[35],ans,sum,s1[16][35000],s2[16][35000],aim;void dfs1(int s,LL sum,int l){ s1[s][c1[s]++] = sum; for(int i = l; i < mid; ++i) dfs1(s+1,sum+a[i],i+1);}void dfs2(int s,LL sum,int l){ s2[s][c2[s]++] = sum; for(int i = l; i < n; ++i) dfs2(s+1,sum+a[i],i+1);}void solve(){ ans = sum = 0; MS(c1,0);MS(c2,0); for(int i = 0; i < n; ++i) scanf("%lld",&a[i]),sum += a[i]; mid = n/2; dfs1(0,0,0);dfs2(0,0,mid); for(int i = 1; i <= 15; ++i) sort(s1[i],s1[i]+c1[i]),sort(s2[i],s2[i]+c2[i]); aim = sum/2; int tem,k; for(int i = 0; i <= mid; ++i) { tem = mid-i; k = c2[tem]-1; for(int j = 0; j < c1[i]; ++j) { while(s1[i][j]+s2[tem][k]>aim && k>0) k--; if(s1[i][j]+s2[tem][k]>aim) break; gmax(ans,s1[i][j]+s2[tem][k]); } if(n&1) { tem++; k = c2[tem]-1; for(int j = 0; j < c1[i]; ++j) { while(s1[i][j]+s2[tem][k]>aim && k>0) k--; if(s1[i][j]+s2[tem][k]>aim) break; gmax(ans,s1[i][j]+s2[tem][k]); } } } printf("%lld\n",sum-2*ans);}int main(){ //fre(); while(~scanf("%d",&n)) solve(); return 0;}
1 0
- hdu 3017 Treasure Division 折半枚举 + 双指针
- 折半搜索+二分 Treasure Division hdu 3017
- [HDU 3017] Treasure Division (暴力+折半搜索)
- [Meet In Middle] HDU 3017 Treasure Division
- hdu 5735 Born Slippy 折半枚举
- Hdu 5936 Difference【思维+折半枚举+二分】
- HDU 5936 Difference(折半枚举)
- HDU 5936 Difference 折半枚举,暴力
- hdu 4091 Zombie’s Treasure Chest 贪心+枚举
- HDU 4091Zombie’s Treasure Chest(贪心+枚举)
- HDU 4091 Zombie’s Treasure Chest(贪心+枚举)
- 【折半枚举】
- 折半枚举
- 折半枚举
- UVA725 Division【枚举】
- UVa 725----Division(枚举)
- Division(简单枚举)
- UVA725 Division【暴力枚举】
- 替换字符串中的空格4
- 慕课网二次学习(一)
- MyBatis和Hibernate相比,优势在哪里?
- Image Retrieval paper list of Liang Zheng
- Java多线程编程(一):创建并运行Java线程
- hdu 3017 Treasure Division 折半枚举 + 双指针
- UINavigationBar 设置透明 和去掉返回按钮
- Java文件流 字节流和字符流
- 2016武汉科技大学邀请赛现场赛 E题
- Android Fragment 真正的完全解析(上)
- Android开发笔记之ListView实现网络图片的显示
- android中如何将下载的图片保存到手机SD(外部存储)卡中
- uva 10652(凸包)
- innobackupex恢复操作报错两例