搜索应用-计算最优解
借 用 背 包 原 理 进 行 思 考
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int f[10];
int bigger(int n, int m){
int sum = 0;
sort(f,f+n);
for(int i=0; i<=n; i++) sum+=f[i];
int p[n+1][sum];
memset(p,0,sizeof(p));
for(int i=0; i<=n; i++){
for(int j=0; j<sum; j++){
if(i==0||j==0) p[i][j] = 0;
else if(j>=f[i] && p[i-1][j-f[i]]+f[i]<=j){
p[i][j] = max(p[i-1][j], p[i-1][j-f[i]]+f[i]);
}else{
p[i][j] = p[i-1][j];
}
}
}
for(int i=0; i<=n; i++){
for(int j=0; j<sum; j++){
if(p[i][j]*m >= sum){
cout<<p[i][j]<<endl;
return 0;
}
}
}
}
int main(){
int n, m;
cin>>n>>m;
for(int i=1; i<=n; i++) scanf("%d", &f[i]);
bigger(n, m);
return 0;
}
利 用 二 分 法 求 解
#include<iostream>
#include<algorithm>
#include<cstring>
#define MAX 100000
using namespace std;
typedef long long llong;
int n, k;
llong T[MAX];
int check(llong p){
int i=0;
for(int j=0; j<k; j++){
llong s=0;
while(s+T[i]<=p){
s+=T[i];
i++;
if(i==n) return n;
}
}
return i;
}
int solve(){
llong left=0;
llong right=100000*100000;
llong mid;
while(right-left>1){
mid=(left+right)/2;
int v=check(mid);
if(v>=n) right = mid;
else left = mid;
}
return right;
}
main(){
cin>>n>>k;
for(int i=0; i<n; i++) cin>>T[i];
llong ans = solve();
cout<<ans<<endl;
}