首页 > 其他分享 >Educational Codeforces Round 153 (Rated for Div. 2)

Educational Codeforces Round 153 (Rated for Div. 2)

时间:2023-08-18 22:46:33浏览次数:56  
标签:Educational Rated 硬币 int Codeforces Alice 01 序列 dp

Educational Codeforces Round 153 (Rated for Div. 2)

这次的div2有点难度,当时b题思路对了,但是没有写好

A题传送门

A题意:

给你一个只包含'('和')'的字符串,要求你将他的长度扩大一倍,并且使得所有括号匹配且组成的序列当中不能存在原序列的子序列

A思路:

这道题一开始写的时候没有注意题意,忽略了序列应该与原序列没有匹配的条件,所以一开始想简单了,理解后,事实上我们只存在两种序列形式,一种是(((,))这种一次出现多个相同的,一种是)(一直是先出现右括号,再出现左括号的,这里事没有一次出现多个相同的,我们只需要改变原序列中出现这两种情况的地方就行,针对第一种情况,我们可以()()()用这个方式改变,针对第二种情况,我们可以用((()))这种方式改变。注意一个特殊情况()这个一定是子序列

A代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve(){
    string s;
    cin>>s;
    // cout<<s<<endl;
    int n=s.size();

    if(s=="()"){
        cout<<"NO"<<endl;
        return ;
    }
    cout<<"YES"<<endl;
    int flag=0;
    for(int i=0;i<n;){
        int ans=1;
        int j=i+1;
        while(s[j]==s[i]){
            ans++;
            j++;
        }
        flag=max(flag,ans);
        i=j;
    }
    if(flag==1){
        for(int i=0;i<n;i++){
            cout<<"(";
        }
        for(int i=0;i<n;i++){
            cout<<")";
        }
    }
    else{
        for(int i=0;i<n;i++){
            cout<<"()";
        }
    }
    cout<<endl;
    
}
int main(){
    int t;
    cin>>t;
    while(t--){
        solve();

    }
    return 0;
}

B题传送门

B题意:

一开始你有a1枚一元硬币,ak枚k元硬币和无限多枚特殊硬币(可以当成一元或者是k元),请使用最少数量的特殊硬币来恰好实现m的价值

B思路:

也许就是一个贪心的思路,我们首先用k元硬币补充,再考虑一元硬币,如果一元硬币的数量和k元硬币的数量够用,那就不需要使用特殊硬币,即使需要特殊硬币,我们也应该首先考虑价值为k的特殊硬币

B代码:

#include<bits/stdc++.h>
using namespace std;
void solve(){
	int m,k,a1,ak;
	cin>>m>>k>>a1>>ak;
	m-=min(m/k,ak)*k;
	if(m<=a1){
		cout<<0<<endl;
	}
	else{
		int ans=(m-a1)/k+(m-a1)%k;
		if(m>=((m-a1)/k+1)*k){
			ans=min(ans,(m-a1)/k+1);
		}
		cout<<ans<<endl;

	}

}
int main(){
	int t;
	cin>>t;
	while(t--){
		solve();
	}
	return 0;
}

C题传送门

C题意:

这是一个博弈游戏,给定一个长度为n的序列,有两位玩家Alice和Bob,Alice先手,第一步将筹码放在任意一个位置上,接下来每一个人都需要将筹码放到当前筹码所在元素的左边并且小于当前筹码所在的元素,直到一人无法操作,另一人即可获胜,求Alice第一步位置的个数

C思路:

我们首先考虑必败的情况,1.当Alice选择的数没有比Bob更小的了,2.当Alice选择的数前面存在一个最小数,比Alice当前数小。其余的情况都是必胜的
我们可以从左往右考虑,假如Alice在i点放了筹码,那么考虑i点前面是否有可选择的必胜状态,如果存在必胜状态,或者是没有可以选择的状态(即i点就是最小值),那么i就是必败状态,我们可以设置两个变量a,b表示i前面的最小值和必胜状态的最小值,如果大于a表示前面有可选状态,大于b表示前面有可选的必胜状态。(如果Alice想赢的话,放的i点前面不能有必胜状态)

C代码:

#include<bits/stdc++.h>
using namespace std;
void solve(){
	int n;
	cin>>n;
	std::vector<int> v(n+1);
	for(int i=1;i<=n;i++){
		cin>>v[i];
	}
	int ans=0;
	int a=v[1];
	int b=1e9;//i前面的必胜状态最小值
	for(int i=2;i<=n;i++){
		if(v[i]>a&&v[i]<b){//有可选状态但是没有必胜状态
			b=min(b,v[i]);
			ans++;
		}
		a=min(a,v[i]);//a表示i前面的最小值,这里是为下一次更新

	}
	cout<<ans<<endl;

}
int main(){
	int t;
	cin>>t;
	while(t--){
		solve();
	}
	return 0;
}

D题传送门

D题意:

给定一个01串s ,每次操作可以交换任意两个数。求当整个串的‘01’和‘10’子序列(可以不连续)相等时的最小操作数。

D思路:

这个看了网上一个思路就豁然开朗,原来是忘记设计偏移量了!!
学习地点
直接考虑dp[ i ] [ j ] [ k ],其中 i 表示前 i 位 , j 表示前 i 位中有多少个 1 , k 表示 10 比 01 子序列多多少个(由于10可能会比01数量少,因此需要有个偏移值,这边直接设偏移值为3000),dp值表示为01翻转的操作数。当第 i 位数为 0 时,10子序列会增加 j 个 , 同理,当第 i 位数为 1 时,01子序列会增加(i - j) 个 。于是得到状态转移方程:

\[dp[i][j+1][k-cnt0]=min(dp[i][j+1][k-cnt0],dp[i-1][j][k]); \]

当s[i] == ‘1’ 时 :

\[dp[i][j][k+cnt1]=min(dp[i][j][k+cnt1],dp[i-1][j][k]+1);//改为0 \]

\[ dp[i][j+1][k-cnt0]=min(dp[i][j+1][k-cnt0],dp[i-1][j][k]);//不改 \]

当s[i] == '0' 时 :

\[dp[i][j][k+cnt1]=min(dp[i][j][k+cnt1],dp[i-1][j][k]);//不改 \]

\[dp[i][j+1][k-cnt0]=min(dp[i][j+1][k-cnt0],dp[i-1][j][k]+1);//改为1 \]

由于是交换01数,所以最终整个串的1的数量已知,操作数为翻转01数的二分之一。最终只需要输出dp[n][cnt1][3000] / 2 即可。

D代码:

#include<bits/stdc++.h>
using namespace std;
int dp[105][105][6000];
void solve() 
{
  memset(dp,0x3f,sizeof dp);
  dp[0][0][3000]=0;
  string s;
  cin>>s;
  s=" "+s;
  int l=s.size();
  int ans=0;
  for(int i=1;i<l;i++){
    if(s[i]=='1'){
      ans++;//记录1的个数
    }
  }
  for(int i=1;i<l;i++){
    for(int j=0;j<i;j++){
      int cnt1=j;
      int cnt0=i-1-j;
      for(int k=500;k<=5500;k++){
        if(s[i]=='1'){
          dp[i][j+1][k-cnt0]=min(dp[i][j+1][k-cnt0],dp[i-1][j][k]);//不改
          dp[i][j][k+cnt1]=min(dp[i][j][k+cnt1],dp[i-1][j][k]+1);//改为0
          
        }
        else{
          dp[i][j+1][k-cnt0]=min(dp[i][j+1][k-cnt0],dp[i-1][j][k]+1);//改为1
          dp[i][j][k+cnt1]=min(dp[i][j][k+cnt1],dp[i-1][j][k]);//不改
         
        }
      }

    }
  }
  cout<<dp[l-1][ans][3000]/2<<endl;

}  
int main(){
  int t;
  // cin>>t;
  t=1;
  
  while(t--){
    solve();
  }
  return 0;

}

标签:Educational,Rated,硬币,int,Codeforces,Alice,01,序列,dp
From: https://www.cnblogs.com/du463/p/17641757.html

相关文章

  • Codeforces Round 881 (Div. 3)
    比赛链接:https://codeforces.com/contest/1843A.SashaandArrayColoring题意:一个数组,可以任意分成任意组,每组的贡献是组最大值减最小值,求最大总贡献思路:一组内只有最大值和最小值有用,所以每组只由两个数组成即可,用贪心的思路,依次取出原数组的最大和最小值成组即可B.LongL......
  • Codeforces Round 893 (Div. 2)
    Preface最战俘的一场,B题写挂一发后整个人脑子就不清醒了,放着D不写去写E1,然后忘了可持久化栈有一个经典的倍增写法,最主要当时暑假前集训我还上去讲了这个东西然后比赛的时候还没想起来后面目送徐神爆切5题成功完成两场从蓝上橙,狠狠地把我这个在紫卡了半年的废物羞辱了一波不过确......
  • Educational Codeforces Round 109 (Rated for Div. 2)
    EducationalCodeforcesRound109(RatedforDiv.2)A-Potion-making思路:求最小操作数即药水最简比#include<bits/stdc++.h>usingnamespacestd;#defineintlonglong//#defineint__int128#definedoublelongdoubletypedefpair<int,int>PII;typedefpair......
  • Codeforces Round 883 (Div. 3)
    比赛链接:https://codeforces.com/contest/1846A.RudolphandCuttheRope题意:给n条绳子,知道一端所在高度坐标和各自绳长,他们另一端都连到一个糖果上,问至少剪掉多少绳子糖果能碰到地面思路:显然只有坐标小于绳长的才能让糖果触地,去掉其他的即可B.RudolphandTic-Tac-Toe题......
  • Codeforces Round 892 (Div. 2)
    CodeforcesRound892(Div.2)目录CodeforcesRound892(Div.2)AUnitedWeStandBOlyaandGamewithArraysCAnotherPermutationProblemDAndreyandEscapefromCapygradEMaximumMonogonosityAUnitedWeStand给定长度为\(n\)的数组a,可以将a中元素添加到空数组b......
  • 2023.08.12 codeforces round 893 div2
    年轻人的第四场div2rank:8217solved:2ratingchange:+31newrating:1354A.Buttons题意:给定a,b,c三种按钮的数量,a按钮只能被Anna按,b按钮只能被Katie按,两个人都可以按c按钮,最后没有按钮可以按的人输,Anna先手,问谁是赢家;两个人肯定优先按c按钮,且Anna是先手,只需比较两人能按的按......
  • Codeforces Round 891 (Div. 3)
    比赛链接:https://codeforces.com/contest/1857A.ArrayColoring题意:一个数列,问能否分成两个和的奇偶性相同的集合思路:因为偶数不改变奇偶性,咱们就统计奇数的个数,能平分成两组就行B.MaximumRounding题意:给一个数,每次可以找一位数不四舍可五入,然后把这个位及后面的数都变成......
  • Educational Codeforces Round 107 (Rated for Div. 2)
    EducationalCodeforcesRound107(RatedforDiv.2)A-ReviewSite思路:数1和3的个数#include<bits/stdc++.h>usingnamespacestd;#defineintlonglong//#defineint__int128#definedoublelongdoubletypedefpair<int,int>PII;typedefpair&l......
  • Codeforces Round 765 (Div. 2) A-E
    A.AncientCivilization好像就是对每个二进制位看一下0多还是1多,选择多的那个数就好了。vp的时候直接猜的,交了一发直接过了voidsolve(){intn=read(),m=read();vector<int>cnt0(m+1),cnt1(m+1);for(inti=1;i<=n;i++){intx=read();for(int......
  • Codeforces Round 893(div2)
    CodeforcesRound893(div2)[A题传送门](Problem-A-Codeforces)A题意:我们有a+b+c个瓶盖,选手1可以拿指定的a个或者c个里面的一个,选手2可以拿指定的b个或者c个里面的一个,可以拿完最后一个的即为获胜者,每个人都有最优策略。A思路:这个题一开始想错了,主要是没有读懂题意,理解清楚......