Codeforces 626F Group Projects(滚动数组+差分dp)

简介: F. Group Projects time limit per test:2 seconds memory limit per test:256 megabytes input:standard input output:standard out...

F. Group Projects

time limit per test:2 seconds
memory limit per test:256 megabytes
input:standard input
output:standard output

There are n students in a class working on group projects. The students will divide into groups (some students may be in groups alone), work on their independent pieces, and then discuss the results together. It takes the i-th student ai minutes to finish his/her independent piece.

If students work at different paces, it can be frustrating for the faster students and stressful for the slower ones. In particular, the imbalance of a group is defined as the maximum ai in the group minus the minimum ai in the group. Note that a group containing a single student has an imbalance of 0. How many ways are there for the students to divide into groups so that the total imbalance of all groups is at most k?

Two divisions are considered distinct if there exists a pair of students who work in the same group in one division but different groups in the other.

Input

The first line contains two space-separated integers n and k (1 ≤ n ≤ 200, 0 ≤ k ≤ 1000) — the number of students and the maximum total imbalance allowed, respectively.

The second line contains n space-separated integers ai (1 ≤ ai ≤ 500) — the time it takes the i-th student to complete his/her independent piece of work.

Output

Print a single integer, the number of ways the students can form groups. As the answer may be large, print its value modulo 109 + 7.

Examples
Input
3 2
2 4 5
Output
3
Input
4 3
7 8 9 10
Output
13
Input
4 0
5 10 20 21
Output
1
Note

In the first sample, we have three options:

  • The first and second students form a group, and the third student forms a group. Total imbalance is 2 + 0 = 2.
  • The first student forms a group, and the second and third students form a group. Total imbalance is 0 + 1 = 1.
  • All three students form their own groups. Total imbalance is 0.

In the third sample, the total imbalance must be 0, so each student must work individually.

题目链接:http://codeforces.com/contest/626/problem/F

题意:给n个人, 让我们分成若干组, 每组的值是最大值减去最小值, 求所有组的和。

思路:显然, 需要用DP的思想, 但是该题DP设计的非常巧妙, 而且状态转移的情况容易考虑不全。

我们用d[i][j][v]表示考虑了前i个数了, 有j个组是开放的(所谓开放指的是只有最小值, 还没有最大值, 还可以进人), 当前值之和为v 的方案数。

我们先排序, 这样, 对于开放的组, 每次的累加量就都是 j*(a[i] - a[i-1])。

那么转移的情况要考虑这么几个:

1. 第i个数单组一组

2.第i个数新开一组, 作为新组的最小值

3.第i个数关闭一组, 作为这个组的最大值。

4.第i个数进入j个组中的某一组。

需要用滚动数组, 否则会爆内存。

吐槽一句:cf的测评机真的是让人心态爆炸,跑的太慢了QAQ

心态崩了,数组开大了,开三维的神TM知道会开大了一点点QAQ

下面给出AC代码:【就当学习了QAQ】

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int mod=1e9+7;
 5 const int maxn=222;
 6 int vis[maxn][maxn][1020];
 7 int a[maxn];
 8 int T,n,k,kase=1;
 9 ll d[2][maxn][1020];
10 inline int read()
11 {
12     int x=0,f=1;
13     char ch=getchar();
14     while(ch<'0'||ch>'9')
15     {
16         if(ch=='-')
17             f=-1;
18         ch=getchar();
19     }
20     while(ch>='0'&&ch<='9')
21     {
22         x=x*10+ch-'0';
23         ch=getchar();
24     }
25     return x*f;
26 }
27 int main()
28 {
29     n=read();
30     k=read();
31     for(int i=1;i<=n;i++)
32     {
33         a[i]=read();
34     }
35     sort(a+1,a+1+n);
36     a[0]=a[1];
37     int u=0;
38     d[u][0][0]=1;
39     for(int i=1;i<=n;i++)
40     {
41         u^=1;
42         memset(d[u],0,sizeof(d[u]));
43         for(int j=0;j<=n;j++)
44         {
45             int add=a[i]-a[i-1];
46             for(int v=0;v<=k;v++)
47             {
48                 if(!d[u^1][j][v])
49                     continue;
50                 if(v+j*add>k)//剪枝, 别忘了, 取模是很费时间的
51                     break;
52                 d[u][j][v+j*add]=(d[u][j][v+j*add]+d[u^1][j][v])%mod;//自己一组
53                 d[u][j][v+j*add]=(d[u][j][v+j*add]+d[u^1][j][v]*j%mod)%mod;//随便扔到一组
54                 if(j>0)
55                 {
56                     d[u][j-1][v+j*add]=(d[u][j-1][v+j*add]+d[u^1][j][v]*j%mod)%mod;//关闭一组,作为终点
57                 }
58                 d[u][j+1][v+j*add]=(d[u][j+1][v+j*add]+d[u^1][j][v])%mod;//开启一组,作为起点
59             }
60         }
61     }
62     ll ans=0;
63     for(int i=0;i<=k;i++)
64     {
65         ans=(ans+d[u][0][i])%mod;
66     }
67     cout<<ans<<endl;
68     return 0;
69 }

 

目录
相关文章
codeforces446—— A.DZY Loves Sequences(DP+枚举)
codeforces446—— A.DZY Loves Sequences(DP+枚举)
86 0
codeforces446—— A.DZY Loves Sequences(DP+枚举)
|
人工智能 JavaScript BI
AtCoder Beginner Contest 222 D - Between Two Arrays(前缀和优化dp)
AtCoder Beginner Contest 222 D - Between Two Arrays(前缀和优化dp)
100 0
洛谷P1216-[USACO1.5][IOI1994]数字三角形 Number Triangles(DP)
洛谷P1216-[USACO1.5][IOI1994]数字三角形 Number Triangles(DP)
洛谷P1216-[USACO1.5][IOI1994]数字三角形 Number Triangles(DP)
HDOJ 1391 Number Steps(打表DP)
HDOJ 1391 Number Steps(打表DP)
121 0
HDOJ 1391 Number Steps(打表DP)
|
人工智能
[Codeforces 1579G] Minimal Coverage | dp最小区间覆盖
题意: 给出n个线段,以及一个无限大的坐标轴,第一个线段以0为起点进行放置,后面的线段必须以前一个的终点为起点放置,这就有两种方式,向左向右
|
人工智能 vr&ar
Atcoder--Candy Distribution II--前缀和+map
题目描述 There are N boxes arranged in a row from left to right. The i-th box from the left contains Ai candies. You will take out the candies from some consecutive boxes and distribute them evenly to M children. Such being the case, find the number of the pairs (l,r) that satisfy the following:
94 0
【1128】N Queens Puzzle (20分)【逻辑题】
【1128】N Queens Puzzle (20分)【逻辑题】 【1128】N Queens Puzzle (20分)【逻辑题】
112 0
|
算法 Python
动态规划法(三)子集和问题(Subset sum problem)
  继续讲故事~~   上次讲到我们的主人公丁丁,用神奇的动态规划法解决了杂货店老板的两个找零钱问题,得到了老板的肯定。之后,他就决心去大城市闯荡了,看一看外面更大的世界。
2444 1