InternBootcamp/internbootcamp/bootcamp/ecointroubles/ecointroubles.py
2025-05-23 15:27:15 +08:00

270 lines
8.2 KiB
Python
Executable file

"""#
### 谜题描述
In the Isle of Guernsey there are n different types of coins. For each i (1 ≤ i ≤ n), coin of type i is worth ai cents. It is possible that ai = aj for some i and j (i ≠ j).
Bessie has some set of these coins totaling t cents. She tells Jessie q pairs of integers. For each i (1 ≤ i ≤ q), the pair bi, ci tells Jessie that Bessie has a strictly greater number of coins of type bi than coins of type ci. It is known that all bi are distinct and all ci are distinct.
Help Jessie find the number of possible combinations of coins Bessie could have. Two combinations are considered different if there is some i (1 ≤ i ≤ n), such that the number of coins Bessie has of type i is different in the two combinations. Since the answer can be very large, output it modulo 1000000007 (109 + 7).
If there are no possible combinations of coins totaling t cents that satisfy Bessie's conditions, output 0.
Input
The first line contains three space-separated integers, n, q and t (1 ≤ n ≤ 300; 0 ≤ q ≤ n; 1 ≤ t ≤ 105). The second line contains n space separated integers, a1, a2, ..., an (1 ≤ ai ≤ 105). The next q lines each contain two distinct space-separated integers, bi and ci (1 ≤ bi, ci ≤ n; bi ≠ ci).
It's guaranteed that all bi are distinct and all ci are distinct.
Output
A single integer, the number of valid coin combinations that Bessie could have, modulo 1000000007 (109 + 7).
Examples
Input
4 2 17
3 1 2 5
4 2
3 4
Output
3
Input
3 2 6
3 1 1
1 2
2 3
Output
0
Input
3 2 10
1 2 3
1 2
2 1
Output
0
Note
For the first sample, the following 3 combinations give a total of 17 cents and satisfy the given conditions: {0 of type 1, 1 of type 2, 3 of type 3, 2 of type 4}, {0, 0, 6, 1}, {2, 0, 3, 1}.
No other combinations exist. Note that even though 4 occurs in both bi and ci, the problem conditions are still satisfied because all bi are distinct and all ci are distinct.
Here is a reference code to solve this task. You can use this to help you genereate cases or validate the solution.
```python
#include <bits/stdc++.h>
using namespace std;
int arr[310], nex[310], T, N;
bool can, isRoot[310];
void dfs(int x, int val) {
if (T < 0) return;
arr[x] += val;
if (nex[x] != -1) {
T -= arr[x];
dfs(nex[x], arr[x]);
}
}
long long int memo[310][100000 + 100];
long long int solve(int pos, int val) {
if (pos == 0) return val == 0;
if (val <= 0) return val == 0;
if (memo[pos][val] != -1) return memo[pos][val];
long long int ret = solve(pos - 1, val);
if (val - arr[pos] >= 0)
ret = (ret + solve(pos, val - arr[pos])) % 1000000007;
return memo[pos][val] = ret;
}
long long int t[100000 + 100];
int main() {
int Q, x, y;
while (cin >> N >> Q >> T) {
for (int i = 1; i <= N; i++) scanf(\"%d\", &arr[i]);
memset(nex, -1, sizeof nex);
memset(isRoot, true, sizeof isRoot);
for (int i = 0; i < Q; i++) {
scanf(\"%d %d\", &x, &y);
nex[x] = y;
isRoot[y] = false;
}
bool in = false;
for (int i = 1; i <= N; i++)
if (isRoot[i] && nex[i] != -1) {
in = true;
dfs(i, 0);
}
if ((Q > 0 && in == false) || T < 0) {
cout << 0 << endl;
return 0;
}
memset(memo, -1, sizeof memo);
t[0] = 1;
for (int i = 1; i <= N; i++)
for (int j = 0; j <= T; j++) {
if (j - arr[i] >= 0) t[j] = (t[j] + t[j - arr[i]]) % 1000000007;
}
cout << t[T] << endl;
}
return 0;
}
```
请完成上述谜题的训练场环境类实现,包括所有必要的方法。
"""
from bootcamp import Basebootcamp
import random
from bootcamp import Basebootcamp
MOD = 10**9 + 7
class Ecointroublesbootcamp(Basebootcamp):
def __init__(self, **params):
super().__init__(**params)
self.n_range = params.get('n_range', (3, 6))
self.max_coin_value = params.get('max_coin_value', 5)
self.max_t = params.get('max_t', 50)
self.max_generate_attempts = params.get('max_generate_attempts', 1000)
def case_generator(self):
for _ in range(self.max_generate_attempts):
try:
n = random.randint(*self.n_range)
max_q = min(n // 2, n - 1)
q = random.randint(0, max_q) if max_q > 0 else 0
if q == 0:
constraints = []
else:
types = list(range(1, n+1))
if 2*q > len(types):
continue
selected = random.sample(types, 2*q)
random.shuffle(selected)
constraints = []
bis = set()
cis = set()
for i in range(q):
b = selected[2*i]
c = selected[2*i+1]
if b == c or b in bis or c in cis:
break
bis.add(b)
cis.add(c)
constraints.append((b, c))
else:
# 成功生成所有约束对
pass
if len(constraints) != q:
continue # 无法生成有效约束,跳过本次尝试
a = [random.randint(1, self.max_coin_value) for _ in range(n)]
t = random.randint(1, self.max_t)
answer = self.__class__.solve(n, q, t, a, constraints)
if answer > 0:
return {
'n': n,
'q': q,
't': t,
'a': a,
'constraints': constraints,
'correct_answer': answer
}
except Exception as e:
continue
# 无法生成有效案例时返回一个默认案例
return {
'n': 3,
'q': 1,
't': 5,
'a': [1, 2, 3],
'constraints': [(1, 2)],
'correct_answer': 1 # 需要根据实际情况修改
}
@staticmethod
def solve(n, q, t, coins, constraints):
arr = [0] + coins.copy()
nex = [-1] * (n + 1)
is_root = [True] * (n + 1)
for b, c in constraints:
nex[b] = c
is_root[c] = False
T = t
in_flag = False
# 处理所有根节点
for i in range(1, n + 1):
if is_root[i] and nex[i] != -1:
in_flag = True
stack = [(i, 0)]
while stack:
x, val = stack.pop()
arr[x] += val
if nex[x] != -1:
T -= arr[x]
stack.append((nex[x], arr[x]))
if (q > 0 and not in_flag) or T < 0:
return 0
# 动态规划处理完全背包问题
dp = [0] * (T + 1)
dp[0] = 1
for i in range(1, n + 1):
a_i = arr[i]
for j in range(a_i, T + 1):
dp[j] = (dp[j] + dp[j - a_i]) % MOD
return dp[T]
@staticmethod
def prompt_func(question_case):
constraints_desc = "\n".join(
f"- More coins of type {b} than type {c}"
for b, c in question_case['constraints']
) if question_case['constraints'] else "No constraints"
return f"""You are a mathematics expert working on coin combination problems. Given:
- {question_case['n']} coin types with values: {', '.join(map(str, question_case['a']))}
- Total required value: {question_case['t']} cents
- Constraints:
{constraints_desc}
Calculate the NUMBER OF VALID COMBINATIONS that satisfy all constraints, modulo 10^9+7.
Present your final answer numerically within [answer][/answer] tags. For example: [answer]42[/answer]"""
@staticmethod
def extract_output(output):
import re
matches = re.findall(r'\[answer\](.*?)\[/answer\]', output, re.DOTALL)
if not matches:
return None
try:
return int(matches[-1].strip())
except:
return None
@classmethod
def _verify_correction(cls, solution, identity):
return solution == identity['correct_answer']