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^l] 為轉移方程,為了保證遞增,j需要大於等於l
- 字首和最佳化
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;
}