其实只是把复习题做了一遍。
1.硬币问题
有1 元、5 元、10 元、50 元、100 元、500 元硬币若干枚,现在要用这些硬币来支付A 元,求最少需要多少枚硬币?
#include <cstdio>
#include <iostream>
using namespace std;
int a;
int tot,now;
int coin[6] = {500,100,50,10,5,1};
int main()
{
scanf("%d",&a);
for(int i = 0; i <= 5; i++)
{
now = a / coin[i];
tot += now;
a -= now * coin[i];
if(a == 0) break;
}
printf("%d",tot);
return 0;
}
2.装载问题n 个物品,第i 个物品重量为wi,选择尽量多的物品使得总重量不超过C
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1001;
int n,c;
int tot;
int w[maxn];
int main()
{
scanf("%d%d",&n,&c);
for(int i = 1; i <= n; i++)
scanf("%d",&w[i]);
sort(w+1, w+1+n);
for(int i = 1; i <= n; i++)
if(w[i] + tot <= c)tot += w[i];
else break;
printf("%d",tot);
return 0;
}
3.部分背包问题
n 个物品,第i 个物品重量为wi,价值为vi. 求在总重量不超过C 的情况下选出物品的总价值最高是多少。物品可以只取一部分,价值重量按比例计算
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 1001;
int n,c;
int totw,totv;
struct data{
int w,v;
double s;
bool operator < (const data &right)const{
return s < right.s;
}
};
data a[maxn];
int main()
{
scanf("%d%d",&n,&c);
for(int i = 1; i <= n; i++)
scanf("%d%d",&a[i].w,&a[i].v),a[i].s = a[i].v / a[i].w;
sort(a+1, a+1+n);
for(int i = 1; i <= n; i++)
if(a[i].w + totw <= c)
{
totw += a[i].w;
totv += a[i].v;
}
else if(totw < c)
{
totv += a[i].v * (c - totw) / a[i].w;
}
else break;
printf("%d",totv);
return 0;
}
4.乘船问题n 个人,第i 个人重量为wi,每艘船载重量均为Ci,最多乘两个人。求最少几艘船能载所有人
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 1001;
int n,c;
int tot,l;
int w[maxn];
int main()
{
scanf("%d%d",&n,&c),l = n;
for(int i = 1; i <= n; i++)
scanf("%d",&w[i]);
for(int i = 1; i <= l; i++)
for(int j = l; j >= i; j--)
{
tot++;
l--;
if(w[i] + w[j]< c) break;
}
printf("%d",tot);
return 0;
}
5.给定n 个区间,每个区间左右端点分别为li; ri,现在要求选出尽量多的区间使得它们两两不相交(不包括端点),问最多能选出几个区间#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 1001;
int n;
int tot,lst;
struct data{
int r,l;
bool operator < (const data &right)const{
if(l == right.l) return r < right.r;
return l < right.l;
}
};
data a[maxn];
int main()
{
scanf("%d",&n);
for(int i = 1; i <= n; i++)
scanf("%d%d",&a[i].r,&a[i].l);
sort(a+1, a+1+n);
for(int i = 1; i <= n; i++)
if(a[i].r >= lst)
{
lst = a[i].l;
tot++;
}
printf("%d",tot);
return 0;
}
6.选点问题
给定n 个区间[li; ri],取尽量少的点使得所有区间内部至少一个点
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 1001;
int n;
int tot,lst;
struct data{
int r,l;
bool operator < (const data &right)const{
return r < right.r || r == right.r && l > right.l;
}
};
data a[maxn];
int main()
{
scanf("%d",&n);
for(int i = 1; i <= n; i++)
scanf("%d%d",&a[i].r,&a[i].l);
sort(a+1, a+1+n);
lst = -1;
for(int i = 1; i <= n; i++)
if(lst < a[i].r)
{
lst = a[i].l;
tot++;
}
printf("%d",tot);
return 0;
}
6.顺序问题
给定n 数ai,再给出n 个数bi,现在要求你重新排列b 的顺序,使得
n
Σai bi 最小
i=1
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 1001;
int n;
int a[maxn],b[maxn];
int aa[maxn],bb[maxn],lst[maxn];
bool cmp(const int &x, const int &y){
return x > y;
}
int main()
{
scanf("%d",&n);
for(int i = 1; i <= n; i++)
scanf("%d%d",&a[i],&b[i]), aa[i] = a[i], bb[i] = b[i];
sort(aa+1, aa+1+n);
sort(bb+1, bb+1+n, cmp);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{
if(a[i] == aa[j]) a[i] = j;
if(b[i] == bb[j]) b[i] = j;
}
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
if(a[i] == b[j]) lst[i] = bb[b[j]];
for(int i = 1; i <= n; i++)
printf("%d ",lst[i]);
return 0;
}