http://acm.hdu.edu.cn/showproblem.php?pid=3552
http://codeforces.com/problemset/problem/352/C
http://codeforces.com/problemset/problem/448/C
http://codeforces.com/problemset/problem/37/D
http://codeforces.com/problemset/problem/57/C
http://codeforces.com/problemset/problem/28/C
http://codeforces.com/problemset/problem/689/E
由于时间原因,题目翻译略.
A
贪心将给定的二元组按照
从大到小排序,显然当某个
值在集合里为最大的时候最好的办法就是贪心把所有
值小于
的二元组全部插入与
相同的集合.
所以枚举所有
,答案即为
的最小值.
#include<bits/stdc++.h> //Ithea Myse Valgulious
namespace chtholly{
typedef long long ll;
#define re0 register int
#define rec register char
#define rel register ll
#define gc getchar
#define pc putchar
#define p32 pc(' ')
#define pl puts("")
/*By Citrus*/
inline int read(){
int x=0,f=1;char c=gc();
for (;!isdigit(c);c=gc()) f^=c=='-';
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return f?x:-x;
}
template <typename mitsuha>
inline bool read(mitsuha &x){
x=0;int f=1;char c=gc();
for (;!isdigit(c)&&~c;c=gc()) f^=c=='-';
if (!~c) return 0;
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return x=f?x:-x,1;
}
template <typename mitsuha>
inline int write(mitsuha x){
if (!x) return 0&pc(48);
if (x<0) x=-x,pc('-');
int bit[20],i,p=0;
for (;x;x/=10) bit[++p]=x%10;
for (i=p;i;--i) pc(bit[i]+48);
return 0;
}
inline char fuhao(){
char c=gc();
for (;isspace(c);c=gc());
return c;
}
}using namespace chtholly;
using namespace std;
const int yuzu=1e5;
typedef int fuko[yuzu|10];
typedef pair<int,int> pii;
pii a[yuzu|10];
int main(){
for (int t=read(),i,zxy=0;t--;){
int n=read(),llx=2e9,maxb=0;
for (i=1;i<=n;++i) a[i]=pii(read(),read());
sort(a+1,a+n+1,greater<pii>());
a[n+1].first=a[0].second=0;
for (i=1;i<=n;++i) maxb=max(maxb,a[i-1].second),llx=min(llx,a[i].first+maxb);
/*maxb是目前的b值的最大值,llx是a+b的最小值.*/
printf("Case %d: %d\n",++zxy,llx);
}
}
B
题目相当于先将所有数向下取整,再将
个数变为向上取整.
令
为一个数向上取整的值减向下取整的值.
显然
在
为整数时取
,否则取
.
我们将
的
值排序,算出
值的和
.
那么我们接下来可以贪心,如果
我们就给它
,否则不变.
因为一个
从向下取整变为向上取整,会带来
的贡献,由于要让绝对值最小,所以当
时就不要动它了.
最后坐等答案出来即可.
#include<bits/stdc++.h> //Ithea Myse Valgulious
namespace chtholly{
typedef long long ll;
#define re0 register int
#define rec register char
#define rel register ll
#define gc getchar
#define pc putchar
#define p32 pc(' ')
#define pl puts("")
/*By Citrus*/
inline int read(){
int x=0,f=1;char c=gc();
for (;!isdigit(c);c=gc()) f^=c=='-';
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return f?x:-x;
}
template <typename mitsuha>
inline bool read(mitsuha &x){
x=0;int f=1;char c=gc();
for (;!isdigit(c)&&~c;c=gc()) f^=c=='-';
if (!~c) return 0;
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return x=f?x:-x,1;
}
template <typename mitsuha>
inline int write(mitsuha x){
if (!x) return 0&pc(48);
if (x<0) x=-x,pc('-');
int bit[20],i,p=0;
for (;x;x/=10) bit[++p]=x%10;
for (i=p;i;--i) pc(bit[i]+48);
return 0;
}
inline char fuhao(){
char c=gc();
for (;isspace(c);c=gc());
return c;
}
}using namespace chtholly;
using namespace std;
typedef double db;
const int aoi=4038;
typedef db kotori[aoi];
kotori a,f,c,dif;
db sum;
int main(){
int i,n=read()<<1;
for (i=1;i<=n;++i){
scanf("%lf",&a[i]);
f[i]=floor(a[i]);
c[i]=ceil(a[i]);
dif[i]=c[i]-f[i];
sum+=c[i]-a[i];
}
int l=1,r=n;
sort(dif+1,dif+n+1);
for (i=1;i<=n>>1;++i){
sum-=dif[sum>0.5?r--:l++];
}printf("%.3lf",abs(sum));
}
C
高妙的动态规划.
接下来首先欣赏xhkxhk大佬暴力压行代码.
#include<bits/stdc++.h>
int i,j=1,a[5010],f[5010][5010];
main(){
for(std::cin>>i;j<=i;j++)std::cin>>a[j];
for(;i;i--)for(j=0;j<i;j++)f[i-1][j]=a[j]<a[i]?std::min(f[i][j]+1,f[i][i]+a[i]-a[j]):f[i][i];
std::cout<<**f;
}
然后介绍介绍标算.
很明显答案不能大于
(我一列一列涂肯定能够刚好涂完的吧.)
然后我们考虑横着涂.
我们考虑区间
,找出区间
内最小数的位置
.
然后我们把
的最下方涂
次,这样要涂的部分转化为
两个部分.
而两个部分的高度都下降了
,就能够分治解决问题.
这样就可以写出dp方程了.
#include<bits/stdc++.h> //Ithea Myse Valgulious
namespace chtholly{
typedef long long ll;
#define re0 register int
#define rec register char
#define rel register ll
#define gc getchar
#define pc putchar
#define p32 pc(' ')
#define pl puts("")
/*By Citrus*/
inline int read(){
int x=0,f=1;char c=gc();
for (;!isdigit(c);c=gc()) f^=c=='-';
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return f?x:-x;
}
template <typename mitsuha>
inline bool read(mitsuha &x){
x=0;int f=1;char c=gc();
for (;!isdigit(c)&&~c;c=gc()) f^=c=='-';
if (!~c) return 0;
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return x=f?x:-x,1;
}
template <typename mitsuha>
inline int write(mitsuha x){
if (!x) return 0&pc(48);
if (x<0) x=-x,pc('-');
int bit[20],i,p=0;
for (;x;x/=10) bit[++p]=x%10;
for (i=p;i;--i) pc(bit[i]+48);
return 0;
}
inline char fuhao(){
char c=gc();
for (;isspace(c);c=gc());
return c;
}
}using namespace chtholly;
using namespace std;
const int aoi=5038; /*葵怎么就这么萌啊~*/
int a[aoi];
int dfs(int l,int r,int h){
if (l>r) return 0;
int m=min_element(a+l,a+r+1)-a;
return min(r-l+1,dfs(l,m-1,a[m])+dfs(m+1,r,a[m])+a[m]-h);
/*[l,r]区间涂色的最小次数是r-l+1次.*/
}
int main(){
int i,n=read();
for (i=1;i<=n;++i) a[i]=read();
write(dfs(1,n,0));
}
D
首先预处理组合数逆元.
我们对
求一波前缀和,然后对
的情况进行
.
令dp[i][j]
表示当前考虑到第
个教室,还有
人没有分配的方法总数.
枚举当前有
人分配到前
个教室(
不能超过
),转移方程为
dp[i][j]=(dp[i][j]+dp[i-1][j-k]*zuhe(x[i]-j+k,k)%mod)%mod
.
最后用
乘从没有选择的学生中取
个学生出来的取法总数即可.
数组开小了wa了一发.
#include<bits/stdc++.h> //Ithea Myse Valgulious
namespace chtholly{
typedef long long ll;
#define re0 register int
#define rec register char
#define rel register ll
#define gc getchar
#define pc putchar
#define p32 pc(' ')
#define pl puts("")
/*By Citrus*/
inline int read(){
int x=0,f=1;char c=gc();
for (;!isdigit(c);c=gc()) f^=c=='-';
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return f?x:-x;
}
template <typename mitsuha>
inline bool read(mitsuha &x){
x=0;int f=1;char c=gc();
for (;!isdigit(c)&&~c;c=gc()) f^=c=='-';
if (!~c) return 0;
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return x=f?x:-x,1;
}
template <typename mitsuha>
inline int write(mitsuha x){
if (!x) return 0&pc(48);
if (x<0) x=-x,pc('-');
int bit[20],i,p=0;
for (;x;x/=10) bit[++p]=x%10;
for (i=p;i;--i) pc(bit[i]+48);
return 0;
}
inline char fuhao(){
char c=gc();
for (;isspace(c);c=gc());
return c;
}
}using namespace chtholly;
using namespace std;
const int mod=1e9+7,_=150;
ll dp[_][9999],jic[1098]={1},inv[1098];
int x[_],y[_];
ll kasumi(ll a,ll b=mod-2){
ll s=1;
for (;b;b>>=1,a=a*a%mod) if (b&1) s=s*a%mod;
return s;
}
ll zuhe(int n,int m){
return jic[n]*inv[m]%mod*inv[n-m]%mod;
}
int main(){
int i,j,k,m=read();
for (i=1;i<1098;++i) jic[i]=jic[i-1]*i%mod;
inv[1097]=kasumi(jic[1097]);
for (i=1096;~i;--i) inv[i]=inv[i+1]*(i+1)%mod;
for (i=1;i<=m;++i) x[i]=read()+x[i-1];
for (i=1;i<=m;++i) y[i]=read();
memset(dp,0,sizeof dp);
for (**dp=i=1;i<=m;++i){
for (j=0;j<=x[i];++j){
for (k=0;k<=min(j,y[i]);++k){
dp[i][j]=(dp[i][j]+dp[i-1][j-k]*zuhe(x[i]-j+k,k)%mod)%mod;
}
}
}
ll ans=dp[m][x[m]];
for (i=1;i<=m;++i) ans=ans*zuhe(x[m]-x[i-1],x[i]-x[i-1])%mod;
write(ans);
}
E
我们推一下公式.
假设要求不严格单调递增的序列.不严格单调递减同理,减去所有数都一样的
种情况即可.
令构造出的序列为
,下标是
.我们在
的左边加一个
,右边加一个
.
构造
,则
序列有
项,并且
序列的所有数之和为
.
这种题看起来很像一个隔板法.
.
由于
序列可以为
,我们给两边同时加
.
那么就变成了在
个空里插
个板的问题了.
#include<bits/stdc++.h> //Ithea Myse Valgulious
namespace chtholly{
typedef long long ll;
#define re0 register int
#define rec register char
#define rel register ll
#define gc getchar
#define pc putchar
#define p32 pc(' ')
#define pl puts("")
/*By Citrus*/
inline int read(){
int x=0,f=1;char c=gc();
for (;!isdigit(c);c=gc()) f^=c=='-';
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return f?x:-x;
}
template <typename mitsuha>
inline bool read(mitsuha &x){
x=0;int f=1;char c=gc();
for (;!isdigit(c)&&~c;c=gc()) f^=c=='-';
if (!~c) return 0;
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return x=f?x:-x,1;
}
template <typename mitsuha>
inline int write(mitsuha x){
if (!x) return 0&pc(48);
if (x<0) x=-x,pc('-');
int bit[20],i,p=0;
for (;x;x/=10) bit[++p]=x%10;
for (i=p;i;--i) pc(bit[i]+48);
return 0;
}
inline char fuhao(){
char c=gc();
for (;isspace(c);c=gc());
return c;
}
}using namespace chtholly;
using namespace std;
const int yuzu=2e5,mod=1e9+7;
typedef ll fuko[yuzu|10];
fuko jic={1},inv;
ll kasumi(ll a,ll b=mod-2){
ll s=1;
for (;b;b>>=1,a=a*a%mod) if (b&1) s=s*a%mod;
return s;
}
ll zuhe(int n,int m){
return jic[n]*inv[n-m]%mod*inv[m]%mod;
}
int main(){
int i,n=read();
for (i=1;i<=yuzu;++i) jic[i]=jic[i-1]*i%mod;
for (inv[yuzu]=kasumi(jic[yuzu]),i=yuzu-1;~i;--i) inv[i]=inv[i+1]*(i+1)%mod;
write((zuhe(2*n-1,n)*2%mod-n+mod)%mod);
}
F
用
来解决.
首先预处理组合数.
用
表示目前处理到第
个房间,还有
个人,最长队伍是
的概率.
枚举当前房间进了
个人,概率是从剩下的人中选择了
个人,并且他们都进了这个房间的概率.
dp[i][j-p][max(l,k)]+=dp[i-1][j][k]*c[j][p]*pow(1.0/m,p);
最后用
求得答案.
#include<bits/stdc++.h> //Ithea Myse Valgulious
namespace chtholly{
typedef long long ll;
#define re0 register int
#define rec register char
#define rel register ll
#define gc getchar
#define pc putchar
#define p32 pc(' ')
#define pl puts("")
/*By Citrus*/
inline int read(){
int x=0,f=1;char c=gc();
for (;!isdigit(c);c=gc()) f^=c=='-';
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return f?x:-x;
}
template <typename mitsuha>
inline bool read(mitsuha &x){
x=0;int f=1;char c=gc();
for (;!isdigit(c)&&~c;c=gc()) f^=c=='-';
if (!~c) return 0;
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return x=f?x:-x,1;
}
template <typename mitsuha>
inline int write(mitsuha x){
if (!x) return 0&pc(48);
if (x<0) x=-x,pc('-');
int bit[20],i,p=0;
for (;x;x/=10) bit[++p]=x%10;
for (i=p;i;--i) pc(bit[i]+48);
return 0;
}
inline char fuhao(){
char c=gc();
for (;isspace(c);c=gc());
return c;
}
}using namespace chtholly;
using namespace std;
typedef double db;
const int _=55;
db c[_][_],dp[_][_][_];
int a[_];
int main(){
int i,j,k,p;
for (i=0;i<=_;++i){
for (j=0;j<=i;++j){
c[i][j]=!j?1:c[i-1][j-1]+c[i-1][j];
}
}
int n=read(),m=read();
for (i=1;i<=m;++i) a[i]=read();
db llx=0;
memset(dp,0,sizeof dp);
dp[0][n][0]=1;
for (i=1;i<=m;++i){
for (j=0;j<=n;++j){
for (p=0;p<=j;++p){
for (k=0;k<=n;++k){
int l=ceil(p*1.0/a[i]);
dp[i][j-p][l>k?l:k]+=dp[i-1][j][k]*c[j][p]*pow(1.0/m,p);
}
}
}
}
for (i=1;i<=n;++i) llx+=dp[m][0][i]*i;
printf("%.18lf",llx);
}
G
把这些区间离散化后差分,算每一个最小区间被包括了几次.
如果被包括的次数
,答案即加上长度乘上
的值.
#include<bits/stdc++.h> //Ithea Myse Valgulious
namespace chtholly{
typedef long long ll;
#define re0 register int
#define rec register char
#define rel register ll
#define gc getchar
#define pc putchar
#define p32 pc(' ')
#define pl puts("")
/*By Citrus*/
inline int read(){
int x=0,f=1;char c=gc();
for (;!isdigit(c);c=gc()) f^=c=='-';
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return f?x:-x;
}
template <typename mitsuha>
inline bool read(mitsuha &x){
x=0;int f=1;char c=gc();
for (;!isdigit(c)&&~c;c=gc()) f^=c=='-';
if (!~c) return 0;
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return x=f?x:-x,1;
}
template <typename mitsuha>
inline int write(mitsuha x){
if (!x) return 0&pc(48);
if (x<0) x=-x,pc('-');
int bit[20],i,p=0;
for (;x;x/=10) bit[++p]=x%10;
for (i=p;i;--i) pc(bit[i]+48);
return 0;
}
inline char fuhao(){
char c=gc();
for (;isspace(c);c=gc());
return c;
}
}using namespace chtholly;
using namespace std;
const int yuzu=4e5,mod=1e9+7;
typedef ll fuko[yuzu|10];
fuko sum,jic={1},inv,l,r,li;
ll kasumi(ll a,ll b=mod-2){
ll s=1;
for (;b;b>>=1,a=a*a%mod) if (b&1) s=s*a%mod;
return s;
}
ll zuhe(int n,int m){
return jic[n]*inv[m]%mod*inv[n-m]%mod;
}
int main(){
int cnt=0,i,n=read(),k=read();
for (i=1;i<=yuzu;++i) jic[i]=jic[i-1]*i%mod;
inv[yuzu]=kasumi(jic[yuzu]);
for (i=yuzu-1;~i;--i) inv[i]=inv[i+1]*(i+1)%mod;
for (i=1;i<=n;++i){
l[i]=read(),r[i]=read();
li[cnt++]=l[i],li[cnt++]=++r[i];
}
sort(li,li+cnt);
cnt=unique(li,li+cnt)-li;
#define lb lower_bound
for (i=1;i<=n;++i){
++sum[lb(li,li+cnt,l[i])-li];
--sum[lb(li,li+cnt,r[i])-li];
}
ll llx=0,nk=sum[0];
for (i=1;i<=cnt;++i){
if (nk>=k) llx=(llx+zuhe(nk,k)*(li[i]-li[i-1])%mod)%mod; nk+=sum[i];
}write(llx);
}
谢谢大家.