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

 

posted @ 2013-09-17 23:14  _雨  阅读(350)  评论(0编辑  收藏  举报