这场因为收拾东西准备回家所以没有打,刚刚回家了补一下。
B.智乃买瓜
背包
int n, m;
int w[maxn];
int dp[maxm];
void solve() {
cin >> n >> m;
dp[0] = 1;
if(n == 0) {
for(int i = 1; i <= m; i++)
cout << 0 << ' ';
cout << endl;
return;
}
for(int i = 1; i <= n; i++) {
cin >> w[i];
for(int j = m; j >= w[i]/2; j--) {
if(j-w[i] >= 0)
dp[j] = (dp[j-w[i]/2] + dp[j-w[i]] + dp[j]) % P;
else
dp[j] = (dp[j] + dp[j-w[i]/2]) % P;
}
}
for(int i = 1; i <= m; i++)
cout << dp[i] << ' ';
cout << endl;
}
C.智乃买瓜(another version)
B题逆过来,这种题目还是第一次见,dp[j] = dp[j] + dp[j-w[i]] + dp[j-w[i]/2] 。
int n, m;
int dp[maxm];
vector<int> ans;
void solve() {
cin >> m;
dp[0] = 1;
for(int i = 1; i <= m; i++)
cin >> dp[i];
for(int i = 1; i <= m; i++) {
while(dp[i]) {
ans.pb(2 * i);
for(int j = 0; j <= m; j++) {
if(j + i <= m) {
dp[i+j] -= dp[j];
dp[i+j] = (dp[i+j] + P) % P;
}
if(j + i + i <= m) {
dp[j+i+i] -= dp[j];
dp[i+i+j] = (dp[i+i+j] + P) % P;
}
}
}
}
cout << ans.size() << endl;
for(auto i : ans)
cout << i << ' ';
cout << endl;
}
E.智乃的数字积木(easy version)
按题意模拟即可,把数组分段排序。
int n, m, k;
int col[maxn];
char s[maxn];
int cal(void) {
int ans = 0;
for(int i = 0; i < n; i++) {
ans = (ans * 10 + (s[i]-'0')) % P;
}
return ans;
}
int trans(void){
int l = 0, r = 0;
for(int i = 0; i < n - 1; i++) {
if(col[i] == col[i + 1]) {
r = i + 1;
if(i + 1 == n - 1)
sort(s + l, s + r + 1, greater<char>());
}
else {
sort(s + l, s + r + 1, greater<char>());
r = l = i + 1;
}
}
return cal();
}
void solve() {
cin >> n >> m >> k;
cin >> s;
for(int i = 0; i < n; i++) cin >> col[i];
cout << trans() << endl;
while(k--) {
int p, q;
cin >> p >> q;
for(int i = 0; i < n; i++)
if(col[i] == p) col[i] = q;
cout << trans() << endl;
}
}