您的位置:首页 > 其它

BZOJ-1042 [HAOI2008]硬币购物 容斥原理 +01背包方案数

2017-06-01 21:50 465 查看

大家都很强,可与之共勉。

[HAOI2008]硬币购物

Description

  硬币购物一共有4种硬币。面值分别为c1,c2,c3,c4。某人去商店买东西,去了tot次。每次带di枚ci硬币,买si的价值的东西。请问每次有多少种付款方法。

Input

  第一行 c1,c2,c3,c4,tot 下面tot行 d1,d2,d3,d4,s,其中di,s<=100000,tot<=1000

Output

每次的方法数

Sample Input

1 2 5 10 2

3 2 3 1 10

1000 2 2 2 900

Sample Output

4

27

**************************************************************
Problem: 1042
User: Lazer2001
Language: C++
Result: Accepted
Time:40 ms
Memory:1604 kb
****************************************************************/

#include <cstdio>

unsigned int c[4], d[4], S, T;
unsigned long long dp[100005] = {1}, ans;

void Dfs ( short step, short flag, int sum )  {
if ( sum < 0 )   return;
if ( step == 4 )  {
flag & 1 ?  ans -= dp[sum] : ans += dp[sum];
return;
}
Dfs ( step + 1, flag, sum );
Dfs ( step + 1, flag ^ 1, sum - ( d[step] + 1 ) * c[step] );
}

int main ( )  {
for ( int i = 0; i < 4; ++i )  scanf ( "%d", c + i );
for ( int i = 0; i < 4; ++i )
for ( int j = c[i]; j <= 100000; ++j )
dp[j] += dp[j - c[i]];
for ( scanf ( "%d", &T ); T; --T )  {
for ( int i = 0; i < 4; ++i )  scanf ( "%d", d + i );
scanf ( "%d", &S );
ans = 0;
Dfs ( 0, 0, S );
printf ( "%lld\n", ans );
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: