Title: Give the value of 4 coins and the number of limits, how many ways to make up s block money.
Idea: A very ingenious idea that used 4 of this very small number. We can go ahead and run a full backpack, regardless of the number of each coin. Then you can remove the non-conforming situation. The method is to subtract the number of the extra limit of a coin, then add the number of the two kinds of coins overrun, then subtract the number of three coins, and then add the number of four kinds of coins exceeding the limit. Of course the code is ugly.
CODE:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 100010 #define P (i) (C[i] * (L[i] + 1)) using namespace Std; int C[5],l[5],s;int Cnt;long long F[max],ans; int main () {for (int i = 1; I <= 4; ++i) scanf ("%d", &c[i]); CIN >> CNT; for (int i = 1; I <= cnt; ++i) {for (int j = 1; J <= 4; ++j) scanf ("%d", &l[j]); scanf ("%d", &s); memset (F,0,sizeof (f)); F[0] = 1; for (int _i = 1; _i <= 4, ++_i) for (int j = c[_i]; J <= S; ++j) f[j] + = f[j-c[_i]; ans = f[s]; for (int _i = 1; _i <= 4; ++_i) if (S-p (_i) >= 0) ans-= F[s-p (_i)]; if (s-p (1)-P (2) >= 0) ans + = f[s-p (1)-P (2)]; if (S-p (2)-P (3) >= 0) ans + = f[s-p (2)-P (3)]; if (S-p (3)-P (4) >= 0) ans + = f[s-p (3)-P (4)]; if (S-p (2)-P (4) >= 0) ans + = f[s-p (2)-P (4)]; if (s-p (1)-P (3) >= 0) ans + = f[s-p (1)-P (3)]; if (s-p (1)-P (4) >= 0) ans + = f[s-p (1)-P (4)]; if (s-p (1)-P (2)-P (3) >= 0) ans-= f[s-p (1)-P (2)-P (3)]; if (S-p (2)-P (3)-P (4) >= 0) ans-= f[s-p (2)-P (3)-P (4)]; if (s-p (1)-P (3)-P (4) >= 0) ans-= f[s-p (1)-P (3)-P (4)]; if (s-p (1)-P (2)-P (4) >= 0) ans-= f[s-p (1)-P (2)-P (4)]; if (s-p (1)-P (2)-P (3)-P (4) >= 0) ans + = f[s-p (1)-P (2)-P (3)-P (4)]; printf ("%lld\n", ans); } return 0;}
Bzoj 1042 Haoi 2008 Coin Shopping Allowance principle