高效演算法設計_貪心法(最優裝載問題,部分揹包問題,乘船問題)
阿新 • • 發佈:2019-01-28
最優裝載問題
題目:有一批集裝箱要裝上一艘載重量為c的輪船。其中集裝箱i的重量為Wi。
輸入:
100 6
100 20 25 25 20 20
輸出:
20 20 20 25 25 100
1 1 1 1 0 0
思路:最優裝載問題要求確定在裝載體積不受限制的情況下,將盡可能多的集裝箱裝上輪船。
#include<stdio.h>
#include<algorithm>
using namespace std;
// 貪心選擇裝載
void loading(int box[],int res[],int w,int n){
res[0]=1;
w-=box[0];
for (int i=1;i<n;i++)
{
if(w-box[i]>=0){
w-=box[i];
res[i]=1;
}
}
}
int main()
{
int w,n,i;
int a[10010],ans[10010];
scanf("%d%d",&w,&n);
for(i=0;i<n;i++) scanf("%d",&a[i]);
sort(a,a+n);
for (i=0;i<n;i++) printf("%d " ,a[i]);
printf("\n");
loading(a,ans,w,n);
for (i=0;i<n;i++) printf("%d ",ans[i]);
printf("\n");
return 0;
}
* *
題目:給定n種物品和一個揹包。物品i的重量是Wi,其價值為Vi,揹包的容量為C。
應如何選擇裝入揹包的物品,使得裝入揹包中物品的總價值最大?
注:在選擇裝入揹包的物品時,對每種物品i只有2種選擇,即裝入揹包或不裝入揹包。不能將物品i裝入揹包多次,也不能只裝入部分的物品i。
輸入:
4 50 10 60 30 120 20 100 40 120
輸出:
0 10 6 1.000000
2 20 5 1.000000
1 30 4 0.666667
3 40 3 0.000000
思路:選擇價值大的線裝入,知道裝不進入,將最後一個按照比例裝入
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct node{
int id;
int w;//重量
int v;//價值
int s;//價值除以重量*100
double flag;//標記
}Node;
Node p[1000];//結構體陣列,用來儲存每個物體
int ans[1000];//每個物體拿走的比例
void loading(int n,int c){
int i;
p[0].flag=1;
c-=p[0].w;
for(i=1;i<n;i++){
if((c-p[i].w)>0){
c-=p[i].w;
p[i].flag=1;
}
else break;
}
if(c==0) return;
else{
p[i].flag=(double)c/p[i].w;
return ;
}
}
int main() {
int n,c,i;//c為總重量
scanf("%d%d",&n,&c);
int k=0;
for(i=0;i<n;i++){
scanf("%d %d",&p[i].w,&p[i].v);
p[i].s=p[i].v/p[i].w;
p[i].id=k++;
}
for(i=0;i<n;i++){
for(int j=i;j<n;j++){
if(p[i].s<p[j].s){
Node t=p[i];
p[i]=p[j];
p[j]=t;
}
}
}
loading(n,c);
for(i=0;i<n;i++) printf("%d %d %d %lf\n",p[i].id,p[i].w,p[i].s,p[i].flag);
return 0;
}
乘船問題
題目:有n個人,第i個人重量為Wi。每艘船的最大載重量均為C,且最多隻能乘兩個人。用最少的船裝載所有人。
輸入:
7
150
40 50 90 105 110 120 130
7
140
40 50 90 105 110 120 130
7
130
70 80 90 100 110 120 130
輸出:
6
40 6 50 6 90 5 105 4 110 3 120 2 130 1
6
40 6 50 6 90 5 105 4 110 3 120 2 130 1
Wrong!
#include <stdio.h>
int a[10010],ans[10010],vis[10010];
int count=1;
int loading (int n,int m){
int i,j;
if(m<=a[n-1]) return -1;
for(i=0;i<n;i++){
for(j=n-1;j>i;j--){
if(vis[j]==0 && (a[i]+a[j])<=m){
ans[i]=ans[j]=count++;//一起搭船
// printf("%d %d\n",a[i],a[j]);
vis[i]=vis[j]=1;
}
else if(vis[j]==0 && a[i]+a[j]>m){
ans[j]=count++;//獨自乘船
// printf("%d %d\n",a[i],a[j]);
vis[j]=1;
}
}
}
printf("%d\n",count-1);
return 1;
}
int main() {
int n,m,i,j;
while(scanf("%d %d",&n,&m)!=EOF){
for(i=0;i<n;i++) scanf("%d",&a[i]);
//冒泡
for(int i=0;i<n;i++){
for(j=i;j<n;j++){
if(a[i]>a[j]){
int t=a[i];
a[i]=a[j];
a[j]=t;
}
}
}
// for(int i=0;i<n;i++) printf("%d %d ",a[i],ans[i]);
// printf("\n");
int k=loading (n,m);
if(k<0) printf("Wrong!");
else{
for(i=0;i<n;i++){
printf("%d %d ",a[i],ans[i]);}
}
printf("\n");
}
return 0;
}