XV Open Cup named after E.V. Pankratiev Stage 6, Grand Prix of Japan Problem J. Hyperrectangle

题目大意:

给出一个$d$维矩形,第i维的范围是$[0, l_i]$. 求满足$x_1 + x_2 + ...x_d \leq s$ 的点构成的单纯形体积。

$d, l_i \leq 300$

 

题解:

watashi学长的blog传送门

给出了求$a_1x_1 + a_2x_2 + ...a_dx_d \leq b $的通用做法。答案就是一个神奇的式子$\frac{1}{n!} * \sum_{I \subseteq S}{(-1)^{|I|}}*max\{0, b - \sum_{i \in I}{a_il_i}\}^d$ 

背包一下分别求出取了奇数个和偶数个$l_i$的和的方案数即可。

 

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 310
 5 typedef long long LL;
 6 const int mod = 1e9 + 7; 
 7 const double EPS = 1e-12;
 8 
 9 
10 int a[N]; 
11 int f[2][N * N], g[2][N * N];
12 
13 int pow_mod(int x, int p)
14 {
15      int res = 1;
16     for (; p; p >>= 1)
17     {
18         if (p & 1) res = 1LL * res * x % mod;
19         x = 1LL * x * x % mod;
20     }
21     return res;
22 }
23 
24 int main()
25 { 
26     //freopen("in.txt", "r", stdin);
27        
28        int n, s;
29        cin >> n;
30        for (int i = 1; i <= n; ++i)
31            cin >> a[i];
32     cin >> s;
33     
34     int o = 0;
35     f[0][0] = 1;
36     for (int i = 1; i <= n; ++i)
37     {
38         o ^= 1;
39         memcpy(g[o], g[o ^ 1], sizeof(g[o]));
40         memcpy(f[o], f[o ^ 1], sizeof(f[o]));
41         for (int j = s; j >= a[i]; --j)
42         {
43             f[o][j] += g[o ^ 1][j - a[i]];
44             if (f[o][j] >= mod) f[o][j] -= mod;
45             
46             g[o][j] += f[o ^ 1][j - a[i]];
47             if (g[o][j] >= mod) g[o][j] -= mod;
48         }
49     }
50 
51     int ans = 0;
52     for (int i = 0; i <= s; ++i)
53     {
54         ans += 1LL * pow_mod(s - i, n) * f[o][i] % mod;
55         ans -= 1LL * pow_mod(s - i, n) * g[o][i] % mod;
56         if (ans >= mod) ans -= mod;
57         if (ans < 0) ans += mod;
58     }
59     printf("%d\n", ans);
60     return 0;
61 }

 

posted @ 2018-08-18 20:31  lzw4896s  阅读(428)  评论(0编辑  收藏  举报