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写些简单的大数还挺好的==
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }