• 3139:[HNOI2013]比赛


    题目描述 Description
    沫沫非常喜欢看足球赛,但因为沉迷于射箭游戏,错过了最近的一次足球联赛。此次联赛共N只队伍参加,比赛规则如下:
    (1) 每两支球队之间踢一场比赛。
    (2) 若平局,两支球队各得1分。
    (3) 否则胜利的球队得3分,败者不得分。
    尽管非常遗憾没有观赏到精彩的比赛,但沫沫通过新闻知道了每支球队的最后总得分,然后聪明的她想计算出中多少种可能的比赛情况。
    但沫沫发现当球队较多时,计算工作量将非常大,所以这个任务就交给你了。请你计算出可能的比赛过程的数目,由于答案可能很大,你只需要输出答案对109+7取模的结果。
    输入描述 Input Description
    第一行是一个正整数N。
    接下来一行N个非负整数,依次表示各队的最后得分。
    输入保证20%的数据满足N≤4,40%的数据满足N≤6,60%的数据满足N≤8,100%的数据满足3≤N≤10.
    输出描述 Output Description
    输入答案mod 10^9+7
    样例输入 Sample Input
    4
    4 3 6 4
    样例输出 Sample Output
    3


    其实想一想,还真是那个道理,不是你不懂,是你不敢去做,不敢去想

    每一个对于一个得分序列,不管怎么交换,都不会影响答案,所以我们可以用记忆化搜索,hash一下当前的状态

    但是这个状态必须是i个人,两两之间都没比赛的情况

    我们爆搜每一个人的比赛情况,然后记忆化一下,如果以前已经搜过了,就直接返回答案

    看了题解说状态只有40000左右,我就只开了80000的hash

      1 const
      2     h=30077;
      3     mo=1000000007;
      4 var
      5     a,s:array[0..10]of longint;
      6     nsum,num:array[0..80000]of int64;
      7     next:array[0..80000]of longint;
      8     n,ans,sum,yes,no,tot:longint;
      9     c:array[0..27]of longint;
     10 
     11 procedure init;
     12 var
     13     i,j,t:longint;
     14 begin
     15     read(n);
     16     for i:=1 to n do
     17       begin
     18         read(a[i]);
     19         inc(sum,a[i]);
     20       end;
     21     yes:=sum-n*(n-1);
     22     no:=n*(n-1)>>1-yes;
     23     for i:=n downto 2 do
     24       for j:=1 to i-1 do
     25         if a[j]>a[j+1] then
     26         begin
     27           t:=a[j];
     28           a[j]:=a[j+1];
     29           a[j+1]:=t;
     30         end;
     31 end;
     32 
     33 function hash(x:int64):longint;
     34 begin
     35     exit(trunc(x*10007 mod h));
     36 end;
     37 
     38 function find(x:int64):boolean;
     39 var
     40     i:longint;
     41 begin
     42     i:=hash(x);
     43     while i<>0 do
     44       begin
     45         if num[i]=x then exit(true);
     46         i:=next[i];
     47       end;
     48     exit(false);
     49 end;
     50 
     51 procedure insert(s,x:int64);
     52 var
     53     i:longint;
     54 begin
     55     i:=hash(s);
     56     while (num[i]<>s)and(next[i]<>0) do
     57       i:=next[i];
     58     if num[i]=s then nsum[i]:=(nsum[i]+x)mod mo
     59     else
     60       begin
     61         inc(tot);
     62         next[i]:=tot;
     63         num[tot]:=s;
     64         nsum[tot]:=x;
     65       end;
     66 end;
     67 
     68 function get(x:int64):int64;
     69 var
     70     i:longint;
     71 begin
     72     i:=hash(x);
     73     while (num[i]<>x)and(next[i]<>0) do
     74       i:=next[i];
     75     if num[i]=x then exit(nsum[i])
     76     else exit(0);
     77 end;
     78 
     79 function dfs(x,y:longint):int64;
     80 var
     81     i,j,xi,yi:longint;
     82     ss:int64;
     83 begin
     84     if x=n then exit(1);
     85     if y=x+1 then
     86     begin
     87       ss:=0;
     88       fillchar(c,sizeof(c),0);
     89       for i:=x to n do
     90         inc(c[a[i]-s[i]]);
     91       for i:=27 downto 0 do
     92         for j:=1 to c[i] do
     93           ss:=ss*28+i;
     94       if find(ss) then exit(get(ss));
     95     end;
     96     dfs:=0;
     97     if (s[x]+(n-y+1)*3<a[x])or(s[x]+yes*3+(n-y+1-yes)<a[x]) then exit(dfs);
     98     if y=n then
     99       begin
    100         xi:=x+1;
    101         yi:=xi+1;
    102       end
    103     else
    104       begin
    105         xi:=x;
    106         yi:=y+1;
    107       end;
    108     if yes>0 then
    109     begin
    110       if s[x]+3<=a[x] then
    111       if (y<n)or((y=n)and(s[x]+3=a[x])) then
    112       begin
    113         dec(yes);
    114         inc(s[x],3);
    115         dfs:=(dfs+dfs(xi,yi))mod mo;
    116         inc(yes);
    117         dec(s[x],3);
    118       end;
    119       if s[y]+3<=a[y] then
    120       if (y<n)or((y=n)and(s[x]=a[x])) then
    121       begin
    122         dec(yes);
    123         inc(s[y],3);
    124         dfs:=(dfs+dfs(xi,yi))mod mo;
    125         inc(yes);
    126         dec(s[y],3);
    127       end;
    128     end;
    129     if no>0 then
    130       if (s[x]+1<=a[x])and(s[y]+1<=a[y]) then
    131       if (y<n)or((y=n)and(s[x]+1=a[x])) then
    132       begin
    133         dec(no);
    134         inc(s[x]);
    135         inc(s[y]);
    136         dfs:=(dfs+dfs(xi,yi))mod mo;
    137         inc(no);
    138         dec(s[x]);
    139         dec(s[y]);
    140       end;
    141     if y=x+1 then insert(ss,dfs);
    142 end;
    143 
    144 begin
    145     init;
    146     tot:=h;
    147     write(dfs(1,2));
    148 end.
    View Code
  • 相关阅读:
    asp.net六大对象
    python学习之类和实例的属性;装饰器@property
    第一次写博客,不知道写什么,就随便写一点咯
    Bash脚本编写初体验
    python学习之参数传递
    2016.9.30词法分析程序 108
    实验三 108
    10.28实验二 108
    词法分析实验报告 108
    组合数据类型练习,综合练习 108
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3582388.html
Copyright © 2020-2023  润新知