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

最近跪了两场CF,rating直接回到解放前了,这场DIV2,第二题DP,我一直没贪过去,第三题,也看了,没啥想法。。。

很神的组合题。

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

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

 1 #include <cstdio>

 2 #include <string>

 3 using namespace std;

 4 #define MOD 1000000007

 5 #define LL __int64

 6 int Min(int a,int b)

 7 {

 8     return a < b ? a:b;

 9 }

10 LL bin[1001],c[1001][1001];

11 int flag[1001],a[1001];

12 LL fun(int n,int m)

13 {

14     int i,minz;

15     LL ans = 0;

16     if(n == 0||m == 0)

17     return 1;

18     minz = Min(m+1,n);

19     for(i = 1;i <= minz;i ++)

20     {

21         ans = (ans + c[m+1][i]*c[n-1][i-1])%MOD;

22     }

23     return ans;

24 }

25 int main()

26 {

27     int i,j,n,m,temp,sum,num;

28     LL ans;

29     for(i = 0;i <= 1000;i ++)

30     {

31         c[i][0] = 1;

32     }

33     for(i = 1;i <= 1000;i ++)

34     {

35         for(j = 1;j <= 1000;j ++)

36         c[i][j] = (LL)(c[i-1][j-1] + c[i-1][j])%MOD;

37     }

38     bin[0] = 1;

39     for(i = 1;i <= 1000;i ++)

40     bin[i] = (2*bin[i-1])%MOD;

41     scanf("%d%d",&n,&m);

42     for(i = 1;i <= m;i ++)

43     {

44         scanf("%d",&num);

45         flag[num] = 1;

46     }

47     if(n == m)

48     {

49         printf("1\n");

50         return 0;

51     }

52     num = 1;

53     temp = 0;

54     for(i = 1;i <= n;i ++)

55     {

56         if(flag[i] == 1)

57         {

58             a[num++] = temp;

59             temp = 0;

60         }

61         else

62         temp ++;

63     }

64     ans = fun(temp,a[1]);

65     sum = temp + a[1];

66     for(i = 2;i < num;i ++)

67     {

68         if(a[i] != 0)

69         ans = (((ans*fun(sum,a[i]))%MOD)*bin[a[i]-1])%MOD;

70         sum += a[i];

71     }

72     printf("%I64d\n",ans);

73     return 0;

74 }

 

 

你可能感兴趣的:(codeforces)