您的位置:首页 > 其它

J - 砝码称重 改自51nod1449

2017-06-14 19:22 309 查看

J - 砝码称重

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 128000/64000 KB (Java/Others)
Submit Status

Problem Description

有一个物品和一些已知质量的砝码和天平,问能不能用这些砝码称出这个物品的重量(天平两边都可以放砝码)

Input

多样例输入,样例数<=20000

对于每个样例:

第一行输入两个数n,m,表示砝码数量和重物质量,1 ≤ m ≤ 1018

第二行输入n个数a1 ,a2 , ... ,an ,1018 ≥ ai+1 ≥ 3 * ai ≥ 1

Output

Case x: y

x代表第几个样例,若能称出重物的质量,y为YES,否则y为NO

Sample Input

3 7
1 3 9


Sample Output

Case 1: YES


Hint

样例为一边盘放重物和质量为3的砝码,另一边盘放质量为1和9的砝码

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const double eps = 1e-9;
long long a[40];
int vis[40];
int cas=1;
int check(int n, LL x, LL p)
{
for(int i=n-1;i>=0;--i)
{
if(x - a[i] >= p) x -= a[i], vis[i] = 0;
if(x >= p + a[i]) p += a[i], vis[i] = 2;
}
if(x == p) return 1;
else return 0;
}

int main()
{
//    freopen("1.in","r",stdin);
//    freopen("t1.out","w",stdout);
int T, cas=1;
int n;
LL m;
while(scanf("%d%lld", &n, &m) == 2)
{
for(int i=0;i<n;++i)
scanf("%lld", &a[i]);
sort(a, a+n);
int flag = 0;
long long sum = m;
for(int i=0;i<n&&!flag;++i)
{
memset(vis, 0, sizeof vis);
for(int j=0;j<i;++j) vis[j] = 1;
vis[i] = 2;
if(sum == a[i])
flag = 1;
else
{
flag = check(i, sum, a[i]);
if(!flag)
{
memset(vis, 0, sizeof vis);
for(int j=0;j<i;++j) vis[j] = 1;
flag = check(i, sum, 0);
}
sum += a[i];
}
}
printf("Case %d: ",cas++);
puts(flag?"YES":"NO");
/*        if(flag)
{
LL sum = m;
for(int i=0;i<n;++i) if(vis[i] == 1) printf("%lld ", a[i]), sum += a[i]; puts("");
printf("lsum:%lld\n", sum);
sum = 0;
for(int i=0;i<n;++i) if(vis[i] == 2) printf("%lld ", a[i]), sum += a[i]; puts("");
printf("rsum:%lld\n", sum);
}*/
}

//    printf("time=%.3lf\n",(double)clock()/CLOCKS_PER_SEC);
return 0;
}


solve.cpp

题解:

由砝码质量的上限可知n只有几十。
若a[i]刚好大于m,则不会用到a[i+1],
因为a[1]+a[2]+...+a[i]+m < a[i+1]/2+m <= a[i+1]/2+a[i+1]/3 < a[i+1]
递归执行以下过程
1.每次搜索比m小的a[i]能否凑成m
2.若不可以凑成,则m=a[i]-m,回到1
3.若2还是不可以凑成,则m=m-a[i-1],回到1

搜索能否凑成a[i]时记得剪枝
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: