G - Heavy Coins Gym - 100712G

Bahosain has a lot of coins in his pocket. These coins are really heavy, so he always tries to get rid of some of
the coins by using them when paying for the taxi.
Whenever Bahosain has to pay S pennies for the taxi driver, he tries to choose the maximum number of coin
pieces to pay. The driver will accept receiving more than S pennies only if he can’t remove one or more of the
given coins and still has S or more pennies.
For example, if Bahosain uses the coins of the following values: 2,7and5 to pay 11 pennies, the taxi driver
will not accept this because the coin of value 2 can be removed. On the other hand, when Bahosain uses coins
of 7 and 5to pay 11 pennies, the driver will accept it.
Note that the driver won’t give Bahosain any change back if he receives more than S pennies, and Bahosain
doesn’t care!


Input
The first line of input contains T (1 ≤ T ≤ 1001),the number of test cases.
The first line of each test case contains two integers: N (1 ≤ N ≤ 10)and S (1 ≤ S ≤ 1000),where N is the
number of coins in Bahosain’s pocket and S is the amount (in pennies) Bahosain has to pay for the taxi driver.
The next line contains N space-separated integers between 1 and 100 that represent the values (in pennies)
of the coins in Bahosain’s pocket.


Output
For each test case, print a single line with the maximum number of coins Bahosain can use to pay for the
driver.


Sample Input
2
5 9
4 1 3 5 4
7 37
7 5 8 8 5 10 4

Sample Output
3
6

Note
In the first test case, Bahosain can pay in any of the following ways: (1, 3, 5), (3, 4, 4) or (1, 4, 4).

题意:给出一堆硬币。从硬币中选出一些硬币的值的和大于S并且删除任意硬币后硬币总值小于S,求最大的硬币总数。

题解:

方法一:二进制枚举所有情况。1代表取了硬币,0代表没有取硬币。当硬币总值大于S且除去一个最小值硬币小于S时说明是满足题意的一种取法。在所有取法中取最大的那种。

方法二:dfs遍历所有取法,在所有取法中找到最大值。为了保证硬币的组合删去任意一个硬币后比S小要从大到小遍历。

二进制枚举代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

int main()
{
    int t,a[15],n,s,ans,cnt,cont,minx;
    scanf("%d",&t);
    while(t--)
    {
        ans = 0;
        scanf("%d%d",&n,&s);
        for(int i = 0;i < n;i++) scanf("%d",&a[i]);
        for(int i = 0;i < 1 << n;i++)
        {
            cnt = 0,cont = 0,minx = 1050;
            for(int j = 0;j < n;j++)
            {
                if(i & (1 << j))
                {
                    cont += a[j];
                    cnt++;
                    minx = min(minx,a[j]);
                }
            }
            if(cont - minx < s && cont >= s) ans = max(ans,cnt);
        }
        printf("%d\n",ans);
    }
    return 0;
}

   

dfs代码:

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;

int t,n,s,ans,a[15];

void dfs(int pos,int sum,int cnt)
{
    if(sum >= s)
    {
        ans = max(ans,cnt);
        return;
    }
    if(pos <= 0) return;

    dfs(pos - 1,sum,cnt);//不取当前硬币时的情况//
    dfs(pos - 1,sum + a[pos],cnt + 1);//取当前硬币时的情况//
}

int main()
{
    scanf("%d",&t);
    while(t--)
    {
        ans = 0;
        scanf("%d%d",&n,&s);
        for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
        sort(a + 1,a + 1 + n);
        dfs(n,0,0);
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/eric_chen_song_lin/article/details/81147919
今日推荐