2024.07.27科大讯飞(有困难题)
1. 购房之旅
小强有n个朋友,每个朋友有一定数量的金币,现在他们要购买房子,一共有m个房子,每个房子有两个参数:舒适度和价格,当一个人的金币大于等于一个房子的价格时,才可以购买房子,且要满足以下条件:1.一个人至多购买一个房子。2.一个房子至多被一个人购买。现在小强想知道n个朋友购买的房子的舒适度之和最大可能是多少?
排序再使用红黑树贪心(map或者mutiset)
int main(){
int n; int m;
cin>>n;
cin>>m;
vector<int> coin(n);
map<int,int> mp;
//记录每个人的钱
for(int i=0;i<n;i++){
cin>>coin[i];
mp[coin[i]]++;
}
//记录房子舒适度和对应价格
vector<vector<int>> house(m,vector<int>(2,0));
for(int i=0;i<m;i++){
cin>>house[i][0];
cin>>house[i][1];
}
//尽量使得舒适度最大,对舒适度进行排序,然后顺序遍历房子,同时选择大于房子价格且最接近的金钱去购买
sort(house.begin(),house.end(),[&](auto a,auto b){
if(a[0]==b[0]) return a[1]<b[1];//相同舒适度,价格便宜放前面
return a[0]>b[0];//舒适度高的放前面
});
int res = 0;
for(int i=0;i<m;i++){
auto it = mp.lower_bound(house[i][1]);
if(it!=mp.end()){
res += house[i][0];
mp[it->first]--;
if(mp[it->first]==0)
mp.erase(it->first);
}
}
cout<<res;
return 0;
}
2. base
我们想知道给定一个 10 进制数 n ,其在 2 ~36 进制下的所有进制表示中,含有 1的数量最多是多少。
进行转换计数
int compute(int n,int base){//计算在指定进制下1的个数
int res = 0;
while(n){
if(n%base==1) res++;
n/=base;
}
return res;
}
int main(){
int n;
cin>>n;
int mx = 0;
for(int i=2;i<=36;i++)
mx = max(mx,compute(n,i));
cout<<mx;
return 0;
}
3. 异或和
给定两个整数 n和 m ,询问满足如下条件的序列 a 的数量:
序列a的长度为n;
序列a的值均大于等于0且小于等于m;
序列a是一个非递减序列;
序列a所有元素的异或值为m。
- 首先考虑动态规划,因为结果数量很大
- dp[i][j][k]表示考虑前i个数字,最后一个数字j,异或和为k的方案数。
- 结果为dp[n][m][i]的累加和
- f[i][j][k] += f[i-1][l][k^j] 为转移方程,为了保证递增,l需要小于j,这里使用四个变量也就是四重循环
- 前缀和优化,优化不同结尾的累加和
int main() {
int n, m;
cin >> n >> m;
// f[i][k][l]表示前i个数字,异或和为k,以l为结尾的方案数
vector<vector<vector<ll>>> f(n + 1, vector<vector<ll>>(2 * m + 1, vector<ll>(m + 1, 0)));
f[0][0][0] = 1;//初始状态
for (int i = 1; i <= n; ++i) {//遍历n个数作为上限
// 前缀和数组
vector<vector<ll>> pre(2 * m + 1, vector<ll>(m + 1, 0));
for (int t = 0; t <= 2 * m; ++t) {
for (int p = 0; p <= m; ++p) {
pre[t][p] = f[i - 1][t][p];
if (p != 0) pre[t][p] = (pre[t][p] + pre[t][p - 1]) % MOD;
}
}
for (int k = 0; k <= 2 * m; ++k) {
for (int l = 0;l <= m && (k ^ l) <= 2 * m; ++l) {
f[i][k][l] = (f[i][k][l] + pre[k ^ l][l]) % MOD;
}
}
}
ll ans = 0;
for (int i = 0; i <= m; ++i) {
ans = (ans + f[n][m][i]) % MOD;
}
cout << ans << endl;
return 0;
}