吉首大学新生赛 Jack的宝物问题 (前缀和应用)


今天做新生赛,发现自己还是个菜狗.

题目描述

Jack是个吃鸡玩家,一个偶然的机会Jack来到了神秘的P城,Jack发现P城有 N 种宝物,每种宝物有 x[i] 个。但是当Jack想把他们全部拿走时,Jack发现由于背包限制,Jack现在只能带 3 件宝物回去,且每种宝物Jack最多只能带走 1 件。那么Jack一共有多少种带走 3 种不同宝物的方法?

输入

输入题目有多组测试数据
每组数据第一行输入一个m,代表m种类型(3<=m<=2000)
第二行有m个数,表述xi

样例输入

1 2 3

样例输出

6

这个题题意就是有N种物品,同种物品之间也各不相同.问从中存三个的方法数.

这个题暴力的话肯定过不了.
那举个几个例子分析下
如果 N = 4 ,四个值是1 2 3 4,即他们的值与他们的下标相同.
现在来写情况数 (1,2,3),(1,2,4),(1,3,4),(2,3,4);
一共有四种情况,排列上面数对的方式是我们先确定一个值i,然后循环这个值后面的值j,这样就确定了两个数,同理,按照上面的方式确定第三个数.
通过观察上述方式,其实就是第三次循环的时候,将所有j之后的所有数与a[i]a[j] (j后的所有数).这样的话我们就维护一个前缀和,每次到这遍历就可以简化一次循环.

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int a[1010];
bool cmp(int a,int b)
{
    return a > b;
}
int main()
{
    int n;
    int T;
    cin >> T;
    while(T--)
    {
        cin >> n;
        if(n == 1)
        {
            int temp;
            cin >> temp;
            cout << '0' << endl;
            continue;
        }
        for(int i = 0;i <= n - 1; ++i)
        {
            cin >> a[i];
        }
        sort(a,a+n,cmp);
        int t = 0;
        for(int i = 0; ; ++i)
        {
            if(a[i] <= t)
            {
                cout << t << endl;
                break;
            }
            t++;
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值