D
统计子节点中1的个数即可(类似树形dp?)
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<map>using namespace std;
typedef long long LL;
#define int long long
typedef pair<int,int> PII;
const int N=1000010;
int a[N];
string x;
int dp[N];
std::vector<int> v[N];
void dfs(int u,int fa){if(x[u]=='1') dp[u]=1;for(auto c:v[u]){if(c==fa) continue;dfs(c,u);dp[u]+=dp[c];}
}
void solve(){int n;cin>>n;cin>>x;x=","+x;for(int i=1;i<n;i++){int x,y;cin>>x>>y;v[x].push_back(y);v[y].push_back(x); }dfs(1,-1);for(int i=1;i<=n;i++){cout<<dp[i]-(x[i]=='1')<<endl;}}
signed main(){int t=1;//cin>>t;while(t--){solve();}
}
E
我们思考如果当前可以和之前的点重排成一个回文数,那么有两种情况
1.之前出现过的奇偶性质完全相等的(奇-奇=偶 偶-偶=偶)
2.之前出现过的奇偶性质中有一个不同的(奇-偶=奇 偶-奇=奇,这样会有一个值出现次数为奇数,就行 39993 393 ……)
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<map>using namespace std;
typedef long long LL;
#define int long long
typedef pair<int,int> PII;
const int N=1000010;
int a[N];
void solve(){string x;cin>>x;int ans=0;map<vector<int>,int>mp;vector<int>sum;for(int i=0;i<10;i++) sum.push_back(0);mp[sum]++;for(int i=0;i<x.size();i++){sum[x[i]-'0']^=1;ans+=mp[sum];for(int i=0;i<10;i++){vector<int>tt=sum;tt[i]^=1;ans+=mp[tt];}mp[sum]++;}cout<<ans<<endl;
}
signed main(){int t=1;// cin>>t;while(t--){solve();}
}
F
状态压缩dp
变成r对应0
变成e对应1
变成d对应2
可以用三进制模拟
1.首先枚举自己可行的转变的状态j
也就是,在自己这列中,相邻不相等的状态
2.然后再枚举上一列的状态k
如果对于j和k,如果不冲突则可以直接转化
最终答案就是min(dp[m-1][k])
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<map>using namespace std;
typedef long long LL;
#define int long long
typedef pair<int,int> PII;
const int N=1000010;
int a[N];
string str[N];
int tmp[N];
int t[5]={1,3,9,27,81};
int dp[1010][1010];
int n,m;int b[4];
bool check(int num){for(int i=0;i<n;i++){b[i]=num%3;num/=3;}for(int i=1;i<n;i++) if(b[i]==b[i-1]) return false;return true;
}
bool check(int x,int y){for(int i=0;i<n;i++){if(x%3==y%3) return false;x/=3;y/=3;}return true;
}
void solve(){cin>>n>>m;for(int i=0;i<n;i++) cin>>str[i];int ans=1e18;map<char,int>mp;mp['r']=0;mp['e']=1;mp['d']=2;memset(dp,0x3f,sizeof dp);for(int i=0;i<m;i++){for(int j=0;j<t[n];j++){int res=0;int now=j;if(check(j)){if(!i){for(int k=0;k<n;k++){if(mp[str[k][i]]!=(now%3))res++;now/=3;}dp[i][j]=min(dp[i][j],res);}else{for(int k=0;k<n;k++){if(mp[str[k][i]]!=(now%3))res++;now/=3;}for(int k=0;k<t[n];k++){if(check(j,k)){dp[i][j]=min(dp[i][j],dp[i-1][k]+res);}}}if(i==m-1){ans=min(dp[i][j],ans);}}}}cout<<ans<<endl;
}
signed main(){int t=1;//cin>>t;while(t--){solve();}
}