目录
091:小红的口罩
题目链接:小红的口罩 (nowcoder.com)
题目:
题解:
建小堆
priority_queue<int, vector<int>, greater<int>> heap;
取最小值算入总不适度,翻倍后再重新放入堆中,再取最小值重复进行,直到不适度总和超过k
#include <iostream>
#include<algorithm>
#include <queue>
using namespace std;
typedef long long LL;
const int N=1e5+10;
int n,k;
LL arr[N];
int main()
{
cin>>n>>k;
priority_queue<int, vector<int>, greater<int>> heap;
for(int i=0;i<n;i++)
{
cin>>arr[i];
heap.push(arr[i]);
}
int sum=0,day=0;
while(sum<=k)
{
LL num=heap.top();
heap.pop();
sum+=num;
heap.push(num*2);
day++;
}
cout<<day-1<<endl;
return 0;
}
092:春游
题目链接:春游 (nowcoder.com)
题目:
题解:
贪心+分情况讨论
比较a/2和b/3的大小(即3*a和2*b的大小),计算每种船坐满的平均每人费用
1. 3*a<2*b时,尽量选二人船,不剩下人时,全选两人船
1)最后剩1人时,考虑多一只二人船,或者和船上两人换一只三人船
2. 3*a>=2*b时,尽量选三人船,不剩人时,全选三人船
1)最后剩1人时,考虑多一只二人船或者三人船,或者和船上三人换两只二人船
2)最后剩2人时,考虑多一只二人船或者三人船,或者和船上三人换三只双人船
#include<iostream>
using namespace std;
typedef long long LL;
LL T;
LL n,a,b;
LL func()
{
if(n<=2) return min(a,b);
LL ret=0;
if(3*a<2*b) //尽量选两人船
{
ret+=(n/2) * a;
n %= 2;
if(n==1)
{
ret+=min(min(a,b),b-a);
}
}
else //尽量选三人船
{
ret+=(n/3)*b;
n %= 3;
if(n==1)
{
ret+=min(min(a,b),2*a-b);
}
if(n==2)
{
ret+=min(min(a,b),3*a-b);
}
}
return ret;
}
int main()
{
cin>>T;
while(T--)
{
cin>>n>>a>>b;
cout<<func()<<endl;
}
return 0;
}
093:数位染色
题目链接:数位染色_牛客题霸_牛客网 (nowcoder.com)
题目:
题解:
01背包
建一个bool型的dp数值:
状态表示:dp[i][j]表示前i个对象中挑选几个,总和是否等于j
状态转移方程:
dp为bool型,状态转移方式为 dp[i][j]=dp[i-1][j] || dp[i-1][j-arr[i]
初始化:dp[i][0]=true;
#include <iostream>
using namespace std;
const int N=20, M=N*9;
typedef long long LL;
LL x;
int n=1,sum=0;
int arr[N];
bool dp[N][M];
bool func()
{
if(sum%2==1) return false;
sum/=2;
for(int i=1;i<=n;i++)
{
dp[i][0]=true;
for(int j=arr[i];j<=sum;j++)
{
dp[i][j]=dp[i-1][j] || dp[i-1][j-arr[i]];
}
}
return dp[n][sum];
}
int main()
{
cin>>x;
while(x)
{
arr[n++]=x%10;
sum+=x%10;
x/=10;
}
if(func()) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
return 0;
}
//空间优化
#include <iostream>
using namespace std;
const int N=20, M=N*9;
typedef long long LL;
LL x;
int n=1,sum=0;
int arr[N];
bool dp[M];
bool func()
{
if(sum%2==1) return false;
sum/=2;
dp[0]=true;
for(int i=1;i<=n;i++)
{
for(int j=sum;j>=arr[i];j--)
{
dp[j]=dp[j] || dp[j-arr[i]];
}
}
return dp[sum];
}
int main()
{
cin>>x;
while(x)
{
arr[n++]=x%10;
sum+=x%10;
x/=10;
}
if(func()) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
return 0;
}