By 虎皮玄椒
646 字
2 分钟
CF1398
A. Bad Triangle
给一个非递减数组,问是否存在三个下标对应数组元素无法构成三角形。
由于非递减,则第一、二个元素为最小,若最大元素即最后一个元素可以构成三角形,则不存在无法构成三角形的三个下标;反之则取第一、二和最后一个元素即可。
void solve(){ int n;cin>>n; vector<int> a(n); for(int i=0;i<n;i++){ cin>>a[i]; } if(a[0]+a[1]>a[n-1])cout<<-1<<endl; else cout<<"1 2 "<<n<<endl;}B. Substring Removal Game
有一 01 字符串,每次可以删除一段连续相同的子串,得分为删除的 1 的数量,问先手得到的最大得分。
易得,删除 0 是劣的,若删除 0 后两侧的 1 相连,则下家可以一次性获得原本两侧需要两次的分数;若删除 0 后两侧的 1 不相连,则本次操作没有意义。 即两人均不会删除任意 0。 两人每次的得分只能是原本就相连的 1 的数量。统计连续的 1 的数量,从大到小贪心选择,奇数位的得分即为先手得分。
void solve(){ string s;cin>>s; int n=s.size(); vector<int> cnt; int now=(int)(s[0]=='1'); for(int i=1;i<n;i++){ if(s[i]=='1'){ if(s[i-1]=='0') now=1; else now++; }else{ if(s[i-1]=='1') cnt.push_back(now); now=0; } } cnt.push_back(now); sort(cnt.rbegin(),cnt.rend()); int ans=0; for(int i=0;i<cnt.size();i+=2){ ans+=cnt[i]; } cout<<ans<<endl;}C. Good Subarrays
给定一由 0-9 的整数组成的数组,问有多少好子数组满足数组元素和等于数组长度。
设原数组为 a[n],则好数组 a[l,r] 满足
设数组 b[n] 有 b[i]=a[i]-1,求 b[n] 的前缀和 pre[n],满足 pre[r]-pre[l-1]=0 的位置即为所求位置,用 map 保存不同前缀和的位置,即可快速求出数量。
void solve(){ int n;cin>>n; string s;cin>>s; vector<int> a(n),pre(n); map<int,int> precnt; for(int i=0;i<n;i++) a[i]=s[i]-'0'-1; pre[0]=a[0]; precnt[pre[0]]++; for(int i=1;i<n;i++){ pre[i]=a[i]+pre[i-1]; precnt[pre[i]]++; } int ans=precnt[0]; for(auto [_,it]:precnt){ ans+=(it*(it-1)/2); } cout<<ans<<endl;}D. Colored Rectangles
分别有 对颜色为红、绿、蓝色的小棒,给定每对小棒的长度,每次取颜色不同的两对小棒组成矩形,问组成的所有矩形的面积和最大为多少。
显然对于同色小棒来说,优先取长度长的小棒,故先由大到小排序。
设 dp[i][j][k] 为用了前 i 对红色小棒,前 j 对绿色小棒,前 k 对蓝色小棒后可以达到的最大面积。
状态转移见程序。
signed main(){ int R,G,B;cin>>R>>G>>B; vector<int> r(R+1),g(G+1),b(B+1); for(int i=0;i<R;i++)cin>>r[i]; for(int i=0;i<G;i++)cin>>g[i]; for(int i=0;i<B;i++)cin>>b[i]; sort(r.rbegin(),r.rend()); sort(g.rbegin(),g.rend()); sort(b.rbegin(),b.rend()); vector<vector<vector<int>>> dp(R+1,vector<vector<int>>(G+1,vector<int>(B+1))); int ans=0; for(int i=0;i<=R;i++){ for(int j=0;j<=G;j++){ for(int k=0;k<=B;k++){ if(i<R&&j<G)dp[i+1][j+1][k]=max(dp[i][j][k]+r[i]*g[j],dp[i+1][j+1][k]); if(i<R&&k<B)dp[i+1][j][k+1]=max(dp[i][j][k]+r[i]*b[k],dp[i+1][j][k+1]); if(j<G&&k<B)dp[i][j+1][k+1]=max(dp[i][j][k]+g[j]*b[k],dp[i][j+1][k+1]); ans=max(ans,dp[i][j][k]); } } } cout<<ans<<endl; return 0;}部分信息可能已经过时
