2023-03 垦田计划
解析 二分法
#include <iostream>
using namespace std;
const int N = 1e5+5;
int n,m,k;
int maxt=0;
int t[N],c[N];
int check(int d)
{
long long int sum=0;
if(d<k) return false;
for(int i=0;i<n;++i)
{
if(t[i]>d) sum +=(t[i]-d)*c[i];
}
printf("d=%d sum: %d m=%d \n",d,sum,m);
return sum;
}
//二分模板
int bsreach(int l,int r)
{
while(l<r)
{
int mid=l+r >>1;
printf("l=%d,r=%d,mid=%d ",l,r,mid);
if( check(mid) < m ) r=mid;
else l=mid+1;
}
return l;
}
int main ()
{
cin >> n >> m >> k;
for(int i=0;i<n;++i){
cin >> t[i] >> c[i];
if(maxt<t[i]) maxt=t[i];
}
int l=k,r=maxt;//左右边界,左边界为规定的最小天数k,右边界为给出的最大天数
//最后的答案就在这个区间,进行二分查找
//cout <<maxt<<endl;
int ans=bsreach(l,r);
cout << ans;
}
202212-2 训练计划
解析
202209-2 何以包邮?
解析 01背包问题
#include <iostream>
#include <algorithm>
using namespace std;
const int N=3e5+10;
int n,x;
int v[40];
int dp[40][N];
int main()
{
cin >> n >> x;
int sum=0;
for(int i=1;i<=n;++i)
{
cin >> v[i];
sum +=v[i];
}
int y = sum-x;
for(int i=1;i<=n;++i)
{
for(int j=0;j<=y;++j)
{
dp[i][j] = dp[i-1][j];
if(j>=v[i]) dp[i][j] = max(dp[i-1][j],dp[i-1][j-v[i]]+v[i]);
}
}
int ans=sum - dp[n][y];
cout << ans;
}