Codeforces Round #302 (Div. 1)

本文深入探讨了程序员在大型项目中编写代码时的优化策略,包括如何制定有效的计划以限制错误总数,并通过实例展示了使用完全背包问题解决此类问题的方法。此外,文章还介绍了道路改善问题的解决方案,涉及到树形动态规划的巧妙运用。这些内容对于提高编程效率和理解复杂算法具有重要意义。

转载请注明出处: http://www.cnblogs.com/fraud/           ——by fraud

 

A. Writing Code

Programmers working on a large project have just received a task to write exactly m lines of code. There are n programmers working on a project, the i-th of them makes exactly ai bugs in every line of code that he writes.

Let's call a sequence of non-negative integers v1, v2, ..., vn a plan, if v1 + v2 + ... + vn = m. The programmers follow the plan like that: in the beginning the first programmer writes the first v1 lines of the given task, then the second programmer writes v2 more lines of the given task, and so on. In the end, the last programmer writes the remaining lines of the code. Let's call a plan good, if all the written lines of the task contain at most b bugs in total.

Your task is to determine how many distinct good plans are there. As the number of plans can be large, print the remainder of this number modulo given positive integer mod.

Input

The first line contains four integers nmbmod (1 ≤ n, m ≤ 500, 0 ≤ b ≤ 500; 1 ≤ mod ≤ 109 + 7) — the number of programmers, the number of lines of code in the task, the maximum total number of bugs respectively and the modulo you should use when printing the answer.

The next line contains n space-separated integers a1, a2, ..., an (0 ≤ ai ≤ 500) — the number of bugs per line for each programmer.

Output

Print a single integer — the answer to the problem modulo mod.

Sample test(s)
input
3 3 3 100
1 1 1
output
10
input
3 6 5 1000000007
1 2 3
output
0
input
3 5 6 11
1 2 1
output
0

一个完全背包的问题,cf的3秒,果断上n^3dp

 1 #include <iostream>
 2 #include <sstream>
 3 #include <ios>
 4 #include <iomanip>
 5 #include <functional>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <string>
 9 #include <list>
10 #include <queue>
11 #include <deque>
12 #include <stack>
13 #include <set>
14 #include <map>
15 #include <cstdio>
16 #include <cstdlib>
17 #include <cmath>
18 #include <cstring>
19 #include <climits>
20 #include <cctype>
21 using namespace std;
22 #define XINF INT_MAX
23 #define INF 0x3FFFFFFF
24 #define MP(X,Y) make_pair(X,Y)
25 #define PB(X) push_back(X)
26 #define REP(X,N) for(int X=0;X<N;X++)
27 #define REP2(X,L,R) for(int X=L;X<=R;X++)
28 #define DEP(X,R,L) for(int X=R;X>=L;X--)
29 #define CLR(A,X) memset(A,X,sizeof(A))
30 #define IT iterator
31 typedef long long ll;
32 typedef pair<int,int> PII;
33 typedef vector<PII> VII;
34 typedef vector<int> VI;
35 ll dp[510][510];
36 ll a[510];
37 int main()
38 {
39     ios::sync_with_stdio(false);
40     int n,m,b,MOD;
41     cin>>n>>m>>b>>MOD;
42     for(int i=1;i<=n;i++){
43         cin>>a[i];
44     }
45     dp[0][0]=1;
46     for(int i=1;i<=n;i++){
47         for(int j=1;j<=m;j++){
48             for(int k=0;k<=b;k++){
49                 if(k>=a[i])
50                 dp[j][k]+=dp[j-1][k-a[i]];
51                 dp[j][k]%=MOD;
52             }
53         }
54 
55     }
56     ll ans=0;
57     for(int i=0;i<=b;i++){
58         ans+=dp[m][i];
59         ans%=MOD;
60     }
61     cout<<ans<<endl;
62     return 0;
63 }

 

D. Road Improvement

The country has n cities and n - 1 bidirectional roads, it is possible to get from every city to any other one if you move only along the roads. The cities are numbered with integers from 1 to n inclusive.

All the roads are initially bad, but the government wants to improve the state of some roads. We will assume that the citizens are happy about road improvement if the path from the capital located in city x to any other city contains at most one bad road.

Your task is — for every possible x determine the number of ways of improving the quality of some roads in order to meet the citizens' condition. As those values can be rather large, you need to print each value modulo 1 000 000 007 (109 + 7).

Input

The first line of the input contains a single integer n (2 ≤ n ≤ 2·105) — the number of cities in the country. Next line contains n - 1positive integers p2, p3, p4, ..., pn (1 ≤ pi ≤ i - 1) — the description of the roads in the country. Number pi means that the country has a road connecting city pi and city i.

Output

Print n integers a1, a2, ..., an, where ai is the sought number of ways to improve the quality of the roads modulo 1 000 000 007 (109 + 7), if the capital of the country is at city number i.

Sample test(s)
input
3
1 1
output
4 3 3
input
5
1 2 3 4
output
5 8 9 8 5

树形dp

一开始看完D题,一想,这不是树形DP水题嘛,中间用个除法,逆元搞一搞就好了。。。然后就被petr给hack了。。。原因便是会发生除0的情况,于是,我们需要避免出现除法。

那么我们需要统计出不包括这个子树的,并且以其父亲为根的方案数。

 1 #include <iostream>
 2 #include <sstream>
 3 #include <ios>
 4 #include <iomanip>
 5 #include <functional>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <string>
 9 #include <list>
10 #include <queue>
11 #include <deque>
12 #include <stack>
13 #include <set>
14 #include <map>
15 #include <cstdio>
16 #include <cstdlib>
17 #include <cmath>
18 #include <cstring>
19 #include <climits>
20 #include <cctype>
21 using namespace std;
22 #define XINF INT_MAX
23 #define INF 0x3FFFFFFF
24 #define MP(X,Y) make_pair(X,Y)
25 #define PB(X) push_back(X)
26 #define REP(X,N) for(int X=0;X<N;X++)
27 #define REP2(X,L,R) for(int X=L;X<=R;X++)
28 #define DEP(X,R,L) for(int X=R;X>=L;X--)
29 #define CLR(A,X) memset(A,X,sizeof(A))
30 #define IT iterator
31 typedef long long ll;
32 typedef pair<int,int> PII;
33 typedef vector<PII> VII;
34 typedef vector<int> VI;
35 const ll MOD=1000000007;
36 ll dp[200010];
37 ll dp1[200010];
38 vector<int>G[200010];
39 ll dp2[200010];
40 ll pre[200010];
41 ll last[200010];
42 void dfs(int x){
43     dp[x]=1;
44     for(int i=0;i<G[x].size();i++){
45         int v=G[x][i];
46         dfs(v);
47         dp[x]=dp[x]*(dp[v]+1)%MOD;
48     }
49 }
50 void dfs1(int x){
51     dp1[x]=dp[x]*dp2[x]%MOD;
52     pre[0]=1;
53     for(int i=0;i<G[x].size();i++){
54         int v = G[x][i];
55         pre[i+1]=pre[i]*(dp[v]+1)%MOD;
56     }
57     last[(int)G[x].size()]=1;
58     for(int i=(int)G[x].size()-1;i>=0;i--){
59         int v = G[x][i];
60         last[i]=last[i+1]*(dp[v]+1)%MOD;
61     }
62     for(int i=0;i<G[x].size();i++){
63         int v = G[x][i];
64         dp2[v]=dp2[x]*pre[i]%MOD*last[i+1]%MOD;
65         dp2[v]++;
66     }
67     for(int i=0;i<G[x].size();i++){
68         int v = G[x][i];
69         dfs1(v);
70     }
71 }
72 int main()
73 {
74     ios::sync_with_stdio(false);
75     int n;
76     cin>>n;
77     int a;
78     for(int i=2;i<=n;i++){
79         cin>>a;
80         G[a].PB(i);
81     }
82     fill(dp2,dp2+n+2,1);
83     dfs(1);
84     dfs1(1);
85     for(int i=1;i<=n;i++)cout<<dp1[i]<<" ";
86     cout<<endl;
87     return 0;
88 }

 

转载于:https://www.cnblogs.com/fraud/p/4486632.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值