Codeforces 626F Group Projects(滚动数组+差分dp)
F. Group Projects
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.
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.
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.
3 2
2 4 5
3
4 3
7 8 9 10
13
4 0
5 10 20 21
1
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】
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+;
const int maxn=;
int vis[maxn][maxn][];
int a[maxn];
int T,n,k,kase=;
ll d[][maxn][];
inline int read()
{
int x=,f=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-')
f=-;
ch=getchar();
}
while(ch>=''&&ch<='')
{
x=x*+ch-'';
ch=getchar();
}
return x*f;
}
int main()
{
n=read();
k=read();
for(int i=;i<=n;i++)
{
a[i]=read();
}
sort(a+,a++n);
a[]=a[];
int u=;
d[u][][]=;
for(int i=;i<=n;i++)
{
u^=;
memset(d[u],,sizeof(d[u]));
for(int j=;j<=n;j++)
{
int add=a[i]-a[i-];
for(int v=;v<=k;v++)
{
if(!d[u^][j][v])
continue;
if(v+j*add>k)//剪枝, 别忘了, 取模是很费时间的
break;
d[u][j][v+j*add]=(d[u][j][v+j*add]+d[u^][j][v])%mod;//自己一组
d[u][j][v+j*add]=(d[u][j][v+j*add]+d[u^][j][v]*j%mod)%mod;//随便扔到一组
if(j>)
{
d[u][j-][v+j*add]=(d[u][j-][v+j*add]+d[u^][j][v]*j%mod)%mod;//关闭一组,作为终点
}
d[u][j+][v+j*add]=(d[u][j+][v+j*add]+d[u^][j][v])%mod;//开启一组,作为起点
}
}
}
ll ans=;
for(int i=;i<=k;i++)
{
ans=(ans+d[u][][i])%mod;
}
cout<<ans<<endl;
return ;
}
Codeforces 626F Group Projects(滚动数组+差分dp)的更多相关文章
- [Codeforces 626F]Group Projects
题目大意: 给定\(n\)个数\(a[1]\sim a[n]\),让你把它分为若干个集合,使每个集合内最大值与最小值的差的总和不超过\(K\).问总方案数. 解题思路: 一道很神的dp题. 首先将数进 ...
- Codeforces 626F Group Projects (DP)
题目链接 8VC Venture Cup 2016 - Elimination Round 题意 把$n$个物品分成若干组,每个组的代价为组内价值的极差,求所有组的代价之和不超过$k$的方案数. ...
- 【滚动数组】 dp poj 1036
题意:一群匪徒要进入一个酒店.酒店的门有k+1个状态,每个匪徒的参数是:进入时间,符合的状态,携带的钱. 酒店的门刚开始状态0,问最多这个酒店能得到的钱数. 思路: dp数组为DP[T][K]. 转移 ...
- [BZOJ1044][HAOI2008]木棍分割 二分 + 单调队列优化dp + 滚动数组优化dp
Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长 ...
- hdu 3392(滚动数组优化dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3392 Pie Time Limit: 6000/3000 MS (Java/Others) Me ...
- bzoj21012101: [Usaco2010 Dec]Treasure Chest 藏宝箱(滚动数组优化dp)
2101: [Usaco2010 Dec]Treasure Chest 藏宝箱 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 592 Solved: ...
- POJ 1159 Palindrome-最长公共子序列问题+滚动数组(dp数组的重复利用)(结合奇偶性)
Description A palindrome is a symmetrical string, that is, a string read identically from left to ri ...
- POJ3624 0-1背包(dp+滚动数组)
Charm Bracelet Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 47440 Accepted: 20178 ...
- HDU 5119 Happy Matt Friends (背包DP + 滚动数组)
题目链接:HDU 5119 Problem Description Matt has N friends. They are playing a game together. Each of Matt ...
随机推荐
- sqlserver 存储过程 增加
CREATE PROCEDURE [dbo].[InsertMessage]( @strTable varchar(), --表名 @strValues nvarchar(), --要插入的数据(用英 ...
- 如何在阿里云linux上部署java项目
前2天把git练了下,敲了很多命令,也借助图形界面增强自己的理解,乘着余热把linux在熟悉下.然后想起以前婷主有让我帮忙搭建的阿里云服务器,所以就想自己试着在阿里云的linux上搭建自己的jav ...
- 自定义结构化config文件
前言 开发过程中我们会经常使用到各种config文件,经常我们会使用appSettings进行设置所用的配置,但是随着配置量的增多,都放在appSettings里面明显是不合适的,一方面配置容易混乱, ...
- 538. Convert BST to Greater Tree
Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original B ...
- 小白的 MySQL 笔记(一)
来自 stackoverflow 的内容居多. 1- MySQL VARCHAR size? 2- 数据库设计范式 3- What is InnoDB and MyISAM in MySQL ? 4- ...
- 干货分享!关于APP导航菜单设计你应该了解的一切
导航菜单是人机交互的最主要的桥梁和平台,主要作用是不让用户迷失方向.现在市面上产品的菜单栏种类繁多,到底什么样的才是优秀的导航菜单设计呢?好的菜单设计不仅能提升整个产品的用户体验,而且还能让用户耳目一 ...
- Swift学习第二天--面向对象
//: Playground - noun: a place where people can play import UIKit var str = "Hello, playground& ...
- 阅读MDN文档之StylingBoxes(五)
目录 BoxModelRecap Box properties Overflow Background clip Background origin Outline Advanced box prop ...
- 使用svn 的解决 处理svn状态冲突
当直接只用版本浏览器进行svn的删除操作是,在客户端svn目录里,出现svn版本错误信息提示,使用 svn 解决命令,处理冲突保存 svn resolve --accept=working PATH( ...
- dJango前言之 socketserver源码
socketserver源码分析: ftpserver=socketserver.ThreadingTCPServer(('127.0.0.1',8080),FtpServer) ftpserver. ...