B. Homecoming
题意:
A->B 花费a元
B->A 花费b元
有p元
求要走到点i,从i上车能在p内到终点。
思路:
1.二分答案
2.倒着模拟
3.dp
dp其实也是倒着模拟
比赛的时候我两种都想到了,问题在于代码实现能力过弱,有必要加强模拟的训练了。
//二分答案:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 +7;
const ll MAXN = 1e6 + 5;
ll n,a,b,p;
ll L,R,mid,ans,last;
string s;
void solve(){
cin>>a>>b>>p;
cin>>s;
ll n=s.size();
L=-1,R=n-1,mid,ans,last;
while(L+1<R){
mid=L+R>>1;
ans=0;
last=mid;
for(int i=mid+1;i<n;++i){
if(s[i]!=s[i-1]){
if(s[i-1]=='A'){
ans+=a;
}else{
ans+=b;
}
last=i;
}
}
if(last!=n-1){
if(s[n-1]=='A'){
ans+=a;
}else{
ans+=b;
}
}
if(ans<=p){
R=mid;
}else{
L=mid;
}
}
cout<<R+1<<endl;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int T;cin>>T;
while(T--){
solve();
}
return 0;
}
//dp:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 +7;
const ll MAXN = 1e6 + 5;
ll n,a,b,p;
char s[MAXN];
ll f[MAXN];
void solve(){
cin>>a>>b>>p;
cin>>s+1;
ll n=strlen(s+1);
if(s[n]=='A') f[n]=a;
else f[n]=b;
f[n+1]=0;
ll pos=n;
for(int i=n-1;i>=1;--i){
if(i==n-1){
f[i]=(s[i]=='A'?a:b);
}
else if(s[i]==s[i+1]){
f[i]=f[i+1];
}else{
f[i]=f[i+1]+(s[i]=='A'?a:b);
}
}
for(int i=1;i<=n;++i){
if(f[i]<=p){
pos=i;
break;
}
}
cout<<pos<<endl;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int T;cin>>T;
while(T--){
solve();
}
return 0;
}
D
题意:
你有n本书,每本书的数量为a[i],你可以花费t[i]让这对应的书加1,求总花费最小并使得a[i]各不相同。
思路:
贪心 multiset
每次把同样数量的书放入一个multiset里,然后把最大的书拿出来保留,其他的书花费的时间加到答案里,再把+1之后书放进去,再反复操作。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 +7;
const ll MAXN = 2e5 + 5;
pair<int,int> a[MAXN];
multiset<int> S;
int main(){
// ios::sync_with_stdio(false);
// cin.tie(0);
ll n;
cin>>n;
for(int i=0;i<n;++i){
cin>>a[i].first;
}
for(int i=0;i<n;++i){
cin>>a[i].second;
}
sort(a,a+n);
ll sum=0,ans=0,now=-1;
for(int i=0;i<n;++i){
while(S.size()&&now<a[i].first){
ll x=*S.rbegin();
ans+=sum-x;
sum-=x;
S.erase(S.find(x));
now++;
}
S.insert(a[i].second);
sum+=a[i].second;
now=a[i].first;
}
while(S.size()){
ll x=*S.rbegin();
ans+=sum-x;
sum-=x;
S.erase(S.find(x));
}
cout<<ans;
return 0;
}