CodeForces 18D Seller Bob :包含win x和sell x的组合,拿取价值为2^x,这个区间被拿过就不能再拿,问所拿最大价值:贪心+大数

注意到一个重要的信息,每个x对应的sell最多只有一个=

2^x>2^(x-1)+2^(x-2)+...+1

因此可以按照x的sell从高到低排序,继而扫每个sell,对于每个sell从原数组结尾到开头扫到第一个win,再更新这个区间不可卖即可

发现函数返回vector写些简单的大数还挺好的==

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<math.h>
 4 #include<algorithm>
 5 #include<vector>
 6 using namespace std;
 7 struct dian{
 8   int w,id;
 9 }a[100005];
10 int cmp(dian n1,dian n2)
11 {
12   if (n1.w==n2.w) return n1.id<n2.id;
13   return n1.w>n2.w;
14 }
15 vector<int>two[5005];
16 vector<int>add(vector<int>v1,vector<int>v2)
17 {
18   vector<int>v;
19   int l=max(v1.size(),v2.size()); 
20   int c=0;
21   for (int i=0;i<l;i++)
22   {
23     int a1=i<v1.size()?v1[i]:0;
24     int a2=i<v2.size()?v2[i]:0;
25     v.push_back((a1+a2+c)%10);
26     c=(a1+a2+c)/10;
27   }
28   if (c) v.push_back(c);
29   return v;
30 }
31 int vis[5005],d[5005];
32 char s[5005][10];
33 int main()
34 {
35   int i,j,k,n,cnt;
36   two[0].push_back(1);
37   for (i=1;i<=3001;i++)
38     two[i]=add(two[i-1],two[i-1]);
39   memset(vis,0,sizeof(vis));
40   scanf("%d",&n);
41   cnt=0;
42   for (i=1;i<=n;i++)
43   {
44     scanf("%s%d",s[i],&d[i]);
45     if (s[i][0]=='s'){
46       a[++cnt].w=d[i];
47       a[cnt].id=i;
48     }
49   }
50   vector<int>ans;
51   ans.push_back(0);
52   if (cnt!=0)sort(a+1,a+cnt+1,cmp);
53   for (i=1;i<=cnt;i++)
54   {
55     k=0;
56     for (j=a[i].id;j>=1;j--)
57       if (vis[j]) k=1;
58       else if (s[j][0]=='w'&&d[j]==a[i].w) break;
59     if (j==0||k) continue;
60     for (k=a[i].id;k>=j;k--) vis[k]=1;
61     ans=add(ans,two[a[i].w]);
62   }
63   for (i=ans.size()-1;i>=0;i--) printf("%d",ans[i]);
64   printf("\n"); 
65   return 0;
66 } 
View Code

题目链接:http://codeforces.com/contest/18/problem/D

posted on 2015-03-26 23:45  xiao_xin  阅读(138)  评论(0编辑  收藏  举报

导航