分析

排序之后
可以证明,枚举最后无法凑出的数然后统计答案一定是OK的
比它值小的必须选
所以可以直接暴力背包
背出方案数暴力加上答案即可
时间复杂度:

代码

//Newcoder 18 D
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>

#define LL long long
#define Lowbit(X) (X&(-X))
#define Lson (X<<1)
#define Rson (X<<1|1)
#define Cl(X,Y) memset((X),(Y),sizeof(X))
#define FOR(i,A,B) for(LL i=A;i<=B;i++)
#define BOR(i,A,B) for(LL i=A;i>=B;i--)
#define FOR_SIDE(i,A) for(LL i=Head[A];i;i=Next[i])
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
const LL MAXN=3e4+10;

LL DP[MAXN],Num[MAXN],Total,Limit,Ans,Sum;
LL Pre[MAXN];

inline void File() {
    freopen(".in","r",stdin);
    freopen(".out","w",stdout);
}

signed main() {
    //File();
    scanf("%lld %lld",&Total,&Limit);
    FOR(i,1,Total) { scanf("%lld",&Num[i]); }
    sort(Num+1,Num+Total+1);
    FOR(i,1,Total) Pre[i]=Pre[i-1]+Num[i];
    FOR(i,1,Total) {
        if(Limit-Pre[i-1]<0) break;
        Cl(DP,0); 
        DP[0]=1;
        Limit-=Pre[i-1];
        FOR(j,i+1,Total) {
            BOR(k,Limit,Num[j])
                DP[k]+=DP[k-Num[j]];
        }    
        FOR(j,max((LL)0,Limit-Num[i]+1),Limit) Ans+=DP[j];
        Limit+=Pre[i-1];
    }
    printf("%lld\n",Ans);
    //fclose(stdin); fclose(stdout);
//    system("pause");
    return 0;
}