首页 > 代码库 > lightoj 1235 Coin Change (IV)(折半枚举)
lightoj 1235 Coin Change (IV)(折半枚举)
- 话说这是俺们学校暑假集训完的一道题,刚看到以为是到水题,后来发现者复杂度也太大了,受不了了,比赛完也没搞出来,然后欣爷说这是折半枚举。然后就摸摸的学了一下,又把这道题写了一下,
- 所谓折半枚举就是先算出来一半,再算一半,然后用二分查找看看能不能搞到这一发状态,可以的话就是可以了,
- 题意:给你两个数n,k,下面再给你n个数,表示你现在有的硬币的面值,每种硬币面值的有两个,看是否可以支付k
- 题解思路:首先以为只有三种状态,直接dfs就好了,后来发现复杂度太大了,然后死了撸就是上面的,详细情残考代码
- 源代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int a[28];
long long a1[20005],a2[20005];
int s,e;
int T;
int t1,t2;
int n,k;
void dfs(int x,long long v) {
if(x==e) {
if(e==n) a1[t1++]=v;
else if(e==n/2) a2[t2++]=v;
return ;
}
for(int i=0; i<=2; i++)
dfs(x+1,v+i*a[x]);
}
int main() {
while(scanf("%d",&T)==1) {
int cases=1;
while(T--) {
memset(a1,0,sizeof(a1));
memset(a2,0,sizeof(a2));
scanf("%d%d",&n,&k);
for(int i=0; i<n; i++)
scanf("%d",&a[i]);
t1=t2=0;
e=n/2;
dfs(0,0);
e=n;
dfs(n/2,0);
sort(a2,a2+t2);
int j,l,mid,r;
for( j=0; j<t1; j++) {
long long h=k-a1[j];
l=0;
r=t2-1;
while(l<=r) {
mid =(l+r)>>1;
if(a2[mid]==h)break;
if(a2[mid]>h) r=mid-1;
else l=mid+1;
}
if(l<=r) break;
}
if(j<t1)
printf("Case %d: Yes\n",cases++);
else
printf("Case %d: No\n",cases++);
}
}
}
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; int a[28]; long long a1[20005],a2[20005]; int s,e; int T; int t1,t2; int n,k; void dfs(int x,long long v) { if(x==e) { if(e==n) a1[t1++]=v; else if(e==n/2) a2[t2++]=v; return ; } for(int i=0; i<=2; i++) dfs(x+1,v+i*a[x]); } int main() { while(scanf("%d",&T)==1) { int cases=1; while(T--) { memset(a1,0,sizeof(a1)); memset(a2,0,sizeof(a2)); scanf("%d%d",&n,&k); for(int i=0; i<n; i++) scanf("%d",&a[i]); t1=t2=0; e=n/2; dfs(0,0); e=n; dfs(n/2,0); sort(a2,a2+t2); int j,l,mid,r; for( j=0; j<t1; j++) { long long h=k-a1[j]; l=0; r=t2-1; while(l<=r) { mid =(l+r)>>1; if(a2[mid]==h)break; if(a2[mid]>h) r=mid-1; else l=mid+1; } if(l<=r) break; } if(j<t1) printf("Case %d: Yes\n",cases++); else printf("Case %d: No\n",cases++); } } }
lightoj 1235 Coin Change (IV)(折半枚举)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。