루오 구 1450 : 동전 쇼핑
주제 설명 :
- 의 교단에서 동전의 네 가지 명칭이있다 (C1, C2, C3, C4는 \) \ .
- 가게에 사람의 이동은 총에, 물건을 구입 (\ T) \ , 시간이 될 때마다 (d_i \) \ 조각 \ (C_I \) 동전, 구매 가치 \ (s_i \) , 얼마나 많은 각 질문 뭔가를 지불 방법.
데이터 범위 :
- \ (d_i, s_i \ 당량 1E5 \)
- \ TOT (\는 \ 1,000 당량)
아이디어 :
- 포함 및 제외 배낭 +
- 각각의 질문은 여러 배낭을 할 것, 그것은 확실히 나올 것입니다.
- 우리가 먼저 각 동전이 발생 무제한 사용할 수있는 경우 어떻게되는지 살펴 보자.
- 배낭 완전히 즉, 사용할 수있는 (F (I) \) \ 동전의 수를 선택하기 위해 각 프로그램을 임의의 횟수를 나타내고, 전사 식있다 \ (F (J) = F (JC (I)) \) .
- 첫째 단 하나의 동전의 경우를 생각해 보자.
- 여기에 프로그램의 수 이상 수 있습니다 (D \) \ A는, 그 결과는 사용이있을 수 있습니다 \ (D + 1, D + 2, ... \) 우리가 필요하므로, 프로그램의 상황의 종류 그는 뺀다.
- 여기에 예제를주고, 그것을 어떻게, 지금은 두 개의 섹션이 있다고 ([2 + \ infin \ ] \) 및 ([3 + \ Infin] \) \ . 내가 싶어 \ ([2,3] \) 난 그냥이 두 간격을 빼기해야 할 영역.
- 그런 다음 우리는 마이너스 선택, 선거는 프로그램의 수를 고려할 필요가 \ (D + 1 \) 동전 프로그램을.
- 이어서 알 \ (ANS = F (S) - (F (S) -C * (D + 1)). \) . 이러한는 선택의 여지가 선거 무한 마이너스입니다 \ (D + 1 \) 입니다.
- 동전의 다양한있다 \ (ANS = F (S) - \ sum_ = {I} 제 1} ^ {F (S-C_I * (D_i + 1)). \.) .
- 그러나이 공식은 그가 때문에 가능한 종, 직접 첨가제 아니라, 단지 감각 (1 \) \ 동전은 제한 유형을 초과 \ (2 \) 동전 한계를 초과하고, 축적 중복 상황에 직접 이어질 것입니다.
- 이 필요한 포함 - 배제 법칙은 그래서 당신이 직접 열거하지만, 비트 연산 열거에 훨씬 쉽게 될 것입니다 수 있습니다, 물론, 네 개의 동전이 있습니다.
코드 :
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
int c[5], d[5], s, T;
ll f[maxn], ans;
int main()
{
for(int i = 1; i <= 4; i++) scanf("%d", &c[i]);
f[0] = 1;
for(int i = 1; i <= 4; i++)
for(int j = c[i]; j <= maxn-5; j++)
f[j] += f[j-c[i]];
scanf("%d", &T);
while(T--)
{
ll ans = 0;
for(int i = 1; i <= 4; i++)
scanf("%d", &d[i]);
scanf("%d", &s);
ans = f[s];
for(int i = 1; i < (1<<4); i++)
{
ll tmp = 0, num = 0;
for(int j = 1; j <= 4; j++)
{
if((1<<(j-1))&i)
{
num++;
tmp += (d[j]+1) * c[j];
}
}
if(tmp > s) continue;
if(num % 2 == 0) ans += f[s-tmp];
else ans -= f[s-tmp];
}
cout << ans << endl;
}
return 0;
}