D. Playoff
当s[i]==0时能力值小的队获胜,则当x可以获胜时,比x小的也都可以获胜
同理当s[i]==1时,比x大的也都可以获胜;
可以推断出答案是一段连续的序列;
需要确定可以获胜的最小值与最大值;
统计1和0出现的次数,cnt1,和cnt2;
最小值需要有pow(2,cnt1)-1个比它小的,最大值有pow(2,cnt2)-1个比它大的;
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
void solve(){
int n,i,j,u,num,num1=0,num2=0;
string s;
cin>>n>>s;
num=pow(2,n);
int l=1,r=num;
for(i=0;i<n;i++){
if(s[i]=='0'){
num1++;
}else{
num2++;
}
}
l=pow(2,num2);
r=num-pow(2,num1)+1;
// cout<<l<<" "<<r<<endl;
for(i=l;i<=r;i++){
cout<<i<<" ";
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t;
t=1;
while(t--){
solve();
}
}
C. Count Binary Strings 动态规划(做的头发要掉完了感觉)
题目:让你求一个长度为n的01序列,给你一个是s[i][j]表示(i,j)区间的限制
s[i][j]为1 表示 i-j 字符全都一样
为2 表示 至少包含两个字符
为0 则无限制
求可以形成的数量;
不用考虑0的情况,对于一个i-j区间当i==j时,很明显限制为1,当i==j-1时,如果i与j所代表的值相同则限制仍为1,如果不同则限制变为2,并且对于所有的i<=j-1,限制都为2,所以可以得出1-j,2-j
3-j.....j-j...所对应的限制一定是22221111此类型的;
所以f[i][j]表示a[1~i-1][j]为2,a[i~j][j]为1的合法的字符串数量,i就是限制2与限制1的分界线
当新增一个字符,如果字符与前一个相同,则i这个分界线不变,j+1;
如果与前一个不相同,分界线转移到j+1.区间长度j+1;
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll mod = 998244353;
ll dp[111][111];
ll dd[111][111];
void solve() {
int n,i,j,u;
cin>>n;
for(i=1; i<=n; i++) {
for(j=i; j<=n; j++) {
cin>>dd[i][j];
}
}
dp[1][1]=2;
for(j=1;j<=n;j++){
for(i=1;i<=j;i++){
bool f=false;
for(u=1;u<i;u++){
if(dd[u][j]==1)f=true;
}
for(u=i;u<=j;u++){
if(dd[u][j]==2)f=true;
}
if(f)dp[i][j]=0;
dp[i][j+1]=(dp[i][j+1]+dp[i][j])%mod;
dp[j+1][j+1]=(dp[j+1][j+1]+dp[i][j])%mod;
}
}
ll sum=0;
for(i=1;i<=n;i++){
sum=(sum+dp[i][n])%mod;
}
cout<<sum;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int t;
t=1;
while(t--) {
solve();
}
}