Gift

题目大意

小 \(T\) 要给他的妹妹买礼物~他会不断地买礼物,直到自己身上没有足够的钱来买任何一件礼物为止,他想知道有多少种方案符合他买礼物的方式。

请输出合法的方案。

解题思路

先不考虑限制,那么就是普通的 01 背包。

如果加上限制,那也是一样的思路,反过来看,"一直到没有足够的钱来买任何一件礼物为止"。

那么枚举没钱不能买的那个礼物,再跑 01 背包即可。

AC CODE

#include <bits/stdc++.h>

using namespace std;

#define int long long

namespace Fread
{
	const int SIZE = 1 << 21;
	char buf[SIZE], *S, *T;
	char getchar()
	{
		if(S == T)
		{
			T = (S = buf) + fread(buf, 1, SIZE, stdin);
			if(S == T) return '\n';
		}
		return *S++;
	}
}

namespace Fwrite
{
	const int SIZE = 1 << 21;
	char buf[SIZE], *S = buf, *T = buf + SIZE;
	void flush()
	{
		fwrite(buf, 1, S - buf, stdout);
		S = buf;
	}
	void putchar(char c)
	{
		*S++ = c;
		if(S == T) flush();
	}
	struct cxr
	{
		~cxr()
		{
			flush();
		}
	} boom;
}

int read()
{
	int x = 0;
	int T = 1;
	char c = getchar();
	while(c < '0' || c > '9')
	{
		if(c == '-') T -= 2;
	}
	while(c >= '0' && c <= '9')
	{
		x = x * 10 + c - '0';
		c = getchar();
	}
	return T * x;
}

void write(int x)
{
	if(x > 9) write(x / 10);
	putchar(x % 10 + '0');
}

int n, k;

int a[1007];

int f[1007];

int sum;

int ans;

const int mod = 1e7 + 7;

bool cmp(int a, int b)
{
	return a > b;
}

signed main()
{
	n = read();
	k = read();
	for(int i = 1; i <= n; ++i) a[i] = read(), sum += a[i];
	sort(a + 1, a + n + 1, cmp);
	if(k >= sum)
	{
		puts("1");
		return 0;
	}
	f[0] = 1;
	for(int i = 1; i <= n; ++i)
	{
		sum -= a[i];
		for(int j = max(0ll, k - sum - a[i] + 1); j <= k - sum; ++j)
			ans = (ans + f[j]) % mod;
		for(int j = k; j >= a[i]; --j)
			f[j] = (f[j] + f[j - a[i]]) % mod;
	}
	write(ans);
	putchar('\n');
	return 0;
}
上一篇:MHA0.58依赖包


下一篇:Qt系列文章016-UDP通信