2013ACM省赛题目

地址就贴这一个吧 都在附近

当时回来也没做做 一伤心了 二是当时实在太弱了

先补两道DP

E题的区间DP

dp[i][j]  截止到i位置以字母j为结束的上升序列 正序 逆序各来一遍 再循环一遍保存一下小于等于J结束的有多少

 1 #include <iostream>   

 2 #include<cstdio>   

 3 #include<cstring>   

 4 #include<algorithm>   

 5 #include<stdlib.h>   

 6 using namespace std;   

 7 #define LL long long   

 8 #define N 100010   

 9 #define mod 2012   

10 LL dp1[N][30];   

11 LL dp2[N][30];   

12 char s[N];   

13 int main()   

14 {   

15     int i,j,k,n;   

16     while(scanf("%d",&n)!=EOF)   

17     {   

18         scanf("%s",s);   

19         memset(dp1,0,sizeof(dp1));   

20         memset(dp2,0,sizeof(dp2));   

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

22         {   

23             k = s[i-1]-'a';   

24             dp1[i][k] = 1;   

25             for(j = 0 ;j < k ; j++)   

26             dp1[i][k]=(dp1[i][k]+dp1[i-1][j])%mod;   

27             for(j = 0 ; j < 26 ; j++)   

28             dp1[i][j] = (dp1[i-1][j]+dp1[i][j])%mod;   

29         }   

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

31         {   

32             for(j = 1 ; j < 26 ; j++)   

33             dp1[i][j] = (dp1[i][j]+dp1[i][j-1])%mod;   

34         }   

35         for(i = n ; i>= 1 ; i--)   

36         {   

37             k = s[i-1]-'a';   

38             dp2[i][k] = 1;   

39             for(j = 0 ; j < k ; j++)   

40             dp2[i][k] = (dp2[i+1][j]+dp2[i][k])%mod;   

41             for(j = 0 ; j < 26 ; j++)   

42             dp2[i][j] = (dp2[i+1][j]+dp2[i][j])%mod;   

43         }   

44         for(i = n ; i >= 1; i--)   

45            for(j = 1 ; j < 26 ; j++)   

46            dp2[i][j] = (dp2[i][j]+dp2[i][j-1])%mod;   

47         int ans = 0;   

48         for(i = 2; i < n ; i++)   

49         {   

50             k = s[i-1]-'a';   

51             if(k!=0)   

52             ans = (ans+dp1[i-1][k-1]*dp2[i+1][k-1])%mod;   

53         }   

54         printf("%d\n",ans);   

55     }   

56     return 0;   

57 }   

58     

59   
View Code

I 题 概率DP

虽然对概率题并不是很了解 不过这题真心不难 我是以比较挫的方法过的 时间卡得还不算多紧 过完发现 就我500多ms 人家都是0ms过的。。

发现好像直接乘就可以了 不用管步数。。概率有待加强。。贴我的三维的

 1 #include <iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 #include<algorithm>

 5 #include<stdlib.h>

 6 using namespace std;

 7 double dp[50][50][2500];

 8 int main()

 9 {

10     int i,j,g,n;

11     while(scanf("%d",&n)!=EOF)

12     {

13         if(!n) break;

14         memset(dp,0,sizeof(dp));

15         double a,b,c,d,e;

16         double aa,bb,cc;

17         scanf("%lf%lf%lf%lf%lf",&a,&b,&c,&d,&e);

18         dp[1][1][0] = 1;

19         for(i = 2; i <= n ; i++)

20             for(j = i; j >= 1 ; j--)

21             {

22                 if(i==n) aa = 1;

23                 else aa = e;

24                 if(j==1) cc = a;

25                 else cc = c;

26                 if(j==2) bb = b;

27                 else bb = d;

28                 for(g = 1 ; g <= 2*(i+1) ; g++)

29                 {

30                     dp[i][j][g] = dp[i][j+1][g-1]*aa+dp[i-1][j-1][g-1]*bb+dp[i-1][j][g-1]*cc;

31                 }

32             }

33         double ans=0;

34         for(i = 1; i <= 2*(n+1) ; i++)

35         {

36             ans+=dp[n][1][i]*i;

37         }

38         printf("%.2lf\n",ans);

39     }

40     return 0;

41 }
View Code

 B题 BFS

  1 #include <iostream>

  2 #include<cstring>

  3 #include<algorithm>

  4 #include<stdlib.h>

  5 #include<cstdio>

  6 #include<queue>

  7 using namespace std;

  8 struct node

  9 {

 10     int u,v,next;

 11 }ed[20100];

 12 int w[2010][2010];

 13 int head[2010],vis[2010],t,n,m;

 14 void init()

 15 {

 16     t= 0 ;

 17     memset(head,-1,sizeof(head));

 18     memset(w,0,sizeof(w));

 19 }

 20 void add(int u,int v)

 21 {

 22     ed[t].u = u;

 23     ed[t].v = v;

 24     ed[t].next = head[u];

 25     head[u] = t++;

 26 }

 27 void spfa(int u,int st)

 28 {

 29     memset(vis,0,sizeof(vis));

 30     queue<int>q;

 31     q.push(u);

 32     vis[u] = 1;

 33     while(!q.empty())

 34     {

 35         int tu = q.front();

 36         q.pop();

 37         w[u][tu] = 1;

 38         w[tu][u] = 1;

 39         for(int i = head[tu] ; i != -1; i = ed[i].next)

 40         {

 41             int tv = ed[i].v;

 42             if(!vis[tv])

 43             {

 44                 vis[tv] = 1;

 45                 q.push(tv);

 46             }

 47         }

 48     }

 49 }

 50 int main()

 51 {

 52     int i,j,k,kk=0;

 53     scanf("%d",&k);

 54     while(k--)

 55     {

 56         init();

 57         kk++;

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

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

 60         {

 61             int u,v;

 62             scanf("%d%d",&u,&v);

 63             add(u,v);

 64         }

 65         int f = 1;

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

 67         {

 68             for(j = 1; j <= n ; j++)

 69             {

 70                 if(!w[i][j])

 71                 {

 72                     spfa(i,j);

 73                     if(!w[i][j])

 74                     spfa(j,i);

 75                 }

 76                 if(!w[i][j])

 77                 {

 78                     f = 0;

 79                     break;

 80                 }

 81             }

 82             if(!f) break;

 83         }

 84         printf("Case %d: ",kk);

 85         if(f)

 86         {

 87             puts("Kalimdor is just ahead");

 88         }

 89         else

 90         puts("The Burning Shadow consume us all");

 91     }

 92     return 0;

 93 }

 94  

 95 

 96 

 97 

 98 /**************************************

 99     Problem id    : SDUT OJ 2604 

100     User name    : shang 

101     Result        : Accepted 

102     Take Memory    : 16412K 

103     Take Time    : 380MS 

104     Submit Time    : 2013-09-18 11:59:41  

105 **************************************/
View Code

 H 题 线段树离线处理

有点小技巧 区间 l,r,s,e

将元素按从小到大排序 区间按e排序 依次插入 询问求和 再按s排序 求差

  1 #include <iostream>

  2 #include<cstdio>

  3 #include<cstring>

  4 #include<algorithm>

  5 #include<stdlib.h>

  6 using namespace std;

  7 #define N 50010

  8 #define lowbit(x) (x&(-x))

  9 #define pp 100000010

 10 #define LL long long

 11 int re[N<<2];

 12 struct node

 13 {

 14     int l,r,id;

 15     LL s,e;

 16 }p[N];

 17 int ans[N][2];

 18 struct mode

 19 {

 20     int id;

 21     LL a;

 22 }q[N];

 23 int s[N<<2];

 24 bool cmp(mode a,mode b)

 25 {

 26     return a.a<b.a;

 27 }

 28 bool cmpp(node a,node b)

 29 {

 30     return a.e<b.e;

 31 }

 32 bool cmppp(node a,node b)

 33 {

 34     return a.s<b.s;

 35 }

 36 void up(int l,int r,int w)

 37 {

 38     s[w] = s[w<<1]+s[w<<1|1];

 39 }

 40 void update(int p,int l,int r,int w)

 41 {

 42     if(l==r)

 43     {

 44         s[w] = 1;

 45         return ;

 46     }

 47     int m = (l+r)>>1;

 48     if(p<=m)

 49     update(p,l,m,w<<1);

 50     else

 51     update(p,m+1,r,w<<1|1);

 52     up(l,r,w);

 53 }

 54 int query(int a,int b,int l,int r,int w)

 55 {

 56     if(a<=l&&b>=r)

 57     {

 58         return s[w];

 59     }

 60     int m = (l+r)>>1,re=0;

 61     if(a<=m)

 62     re+=query(a,b,l,m,w<<1);

 63     if(b>m)

 64     re+=query(a,b,m+1,r,w<<1|1);

 65     return re;

 66 }

 67 int main()

 68 {

 69     int t,i,n,m,kk=0;

 70     scanf("%d",&t);

 71     while(t--)

 72     {

 73         memset(s,0,sizeof(s));

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

 75         kk++;

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

 77         {

 78             scanf("%lld",&q[i].a);

 79             q[i].id = i;

 80         }

 81         sort(q+1,q+n+1,cmp);

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

 83         {

 84             scanf("%d%d%lld%lld",&p[i].l,&p[i].r,&p[i].s,&p[i].e);

 85             p[i].id = i;

 86         }

 87         sort(p+1,p+m+1,cmpp);

 88         int o = 1;

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

 90         {

 91             while(o<=n&&q[o].a<=p[i].e)

 92             {

 93                 update(q[o].id,1,n,1);

 94                 o++;

 95             }

 96             ans[p[i].id][0] = query(p[i].l,p[i].r,1,n,1);

 97         }

 98         memset(s,0,sizeof(s));

 99         sort(p+1,p+m+1,cmppp);

100         o = 1;

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

102         {

103             while(o<=n&&q[o].a<p[i].s)

104             {

105                 update(q[o].id,1,n,1);

106                 o++;

107             }

108             ans[p[i].id][1] = query(p[i].l,p[i].r,1,n,1);

109         }

110         printf("Case #%d:\n",kk);

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

112         printf("%d\n",ans[i][0]-ans[i][1]);

113     }

114     return 0;

115 }

116  

117 

118 

119 

120 /**************************************

121     Problem id    : SDUT OJ 2610 

122     User name    : shang 

123     Result        : Accepted 

124     Take Memory    : 4004K 

125     Take Time    : 400MS 

126     Submit Time    : 2013-09-19 14:37:01  

127 **************************************/
View Code

 

你可能感兴趣的:(ACM)