题解:P12316 [蓝桥杯 2024 国 C] 循环位运算
题目大意
给定
思路
鄙人动态规划不熟,在和机房同学交流后确定是考察动态规划,考虑如何转移。
因为每个数都是
设
接下来考虑如何求解 (A << 1) | (A >> 31),所以我们可以在输入时就预处理好
代码
实现的一些小细节都在注释里面,警钟长鸣。
#include <bits/stdc++.h>
using namespace std;
int n,m;
unsigned int a[1003][33];
long long dp[1003][1003];
int main(){
cin >> n >> m;
for(int i=1;i<=n;i++){
unsigned A; // 注意要非负 防止位运算后成负数 同理 a[i][j] 也要非负
cin >> A;
for(int j=0;j<=31;j++)
{
a[i][j] = A;
A = (A << 1) | (A >> 31);
} // 记得考虑不操作的情况
}
for(int i=1;i<=n;i++)
for(int j=0;j<=m;j++)
for(int k=0;k<=min(31,j);k++) // j-k 不能是负数
dp[i][j] = max(dp[i][j],dp[i-1][j-k]+a[i][k]);
long long ans = -1;
for (int i=0;i<=m;i++)
ans = max(ans,dp[n][i]);
cout << ans;
return 0;
}