您的位置:首页 > 其它

Codeforces Round #178 (Div. 2) C. Shaass and Lights

2013-04-09 21:06 411 查看
最近跪了两场CF,rating直接回到解放前了,这场DIV2,第二题DP,我一直没贪过去,第三题,也看了,没啥想法。。。

很神的组合题。

先是亮的灯泡把暗的灯泡分成很多段,特殊考虑第一段和最后一段(如果存在)。然后中间每一段的组合方式是2^(a[i]-1)。

然后就是把n个有顺序的数,插入m个有顺序的数字(fun函数)。注意精度神马的,各种细节。。

#include <cstdio>
#include <string>
using namespace std;
#define MOD 1000000007
#define LL __int64
int Min(int a,int b)
{
return a < b ? a:b;
}
LL bin[1001],c[1001][1001];
int flag[1001],a[1001];
LL fun(int n,int m)
{
int i,minz;
LL ans = 0;
if(n == 0||m == 0)
return 1;
minz = Min(m+1,n);
for(i = 1;i <= minz;i ++)
{
ans = (ans + c[m+1][i]*c[n-1][i-1])%MOD;
}
return ans;
}
int main()
{
int i,j,n,m,temp,sum,num;
LL ans;
for(i = 0;i <= 1000;i ++)
{
c[i][0] = 1;
}
for(i = 1;i <= 1000;i ++)
{
for(j = 1;j <= 1000;j ++)
c[i][j] = (LL)(c[i-1][j-1] + c[i-1][j])%MOD;
}
bin[0] = 1;
for(i = 1;i <= 1000;i ++)
bin[i] = (2*bin[i-1])%MOD;
scanf("%d%d",&n,&m);
for(i = 1;i <= m;i ++)
{
scanf("%d",&num);
flag[num] = 1;
}
if(n == m)
{
printf("1\n");
return 0;
}
num = 1;
temp = 0;
for(i = 1;i <= n;i ++)
{
if(flag[i] == 1)
{
a[num++] = temp;
temp = 0;
}
else
temp ++;
}
ans = fun(temp,a[1]);
sum = temp + a[1];
for(i = 2;i < num;i ++)
{
if(a[i] != 0)
ans = (((ans*fun(sum,a[i]))%MOD)*bin[a[i]-1])%MOD;
sum += a[i];
}
printf("%I64d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: