01背包问题;
给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。
有以下两大类情况
1、背包剩余空间小于w[k] //w[k]表示重量
则不选这个物品 选前一个物品 B[k][c]=B[k-1][c]
2、(1)选这个物品 则B[k][c]=B[k-1][c-w[k]]+v[k];
(2)不选这个物品 B[k][c]=B[k-1][c];
以下是具体实现代码:
#include<stdio.h>
#define N 6
#define W 21 //B[4][20]代表装进去第1到4个,剩余空间20
int B[N][W]={0}; //N代表装进去前n个,w代表还剩w空间;
int v[6]={0,3,4,5,8,10}; //价值
int w[6]={0,2,3,4,5,9}; //重量
void pack()
{
int k,c;
for(k=1;k<N;k++)
{
for(c=1;c<W;c++)
{
if(w[k]>c)
{B[k][c]=B[k-1][c];}
else
{
int value1=B[k-1][c-w[k]]+v[k];
int value2=B[k-1][c];
if(value1>value2)
{
B[k][c]=value1;
}
else
B[k][c]=value2;
}
}
}
}
int main()
{
pack();
printf("%d",B[5][20]);
return 0;
}
对决匹配:
求系统一场对局都匹配不起来(任意两名用户积分差不等于K)?
输入格式 第一行包含两个个整数N和K。
第二行包含N个整数A1, A2, … AN。
下面是实现代码:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
//动态规划 :类似01背包问题
#define N 100001
#define Max(a,b) a>b?a:b
int main()
{
int n,k; //n为在线人数,k为分数差
scanf("%d%d",&n,&k);
int a[N]={0};
for(int i=0;i<n;i++) //把相同分数存到同一个数组a里面
{
int b;
scanf("%d",&b);
a[b]++;
}
int count=0;
int str[N]={0};
int dp[N]={0};
if(k==0)
{
for(int i=0;i<N;i++)
{
if(a[i]>0)
count++;
}
}
else //按分数差为k分为k组,然后每组进行类似背包问题
{
for(int i=0;i<k;i++)
{
int c=0;
for(int j=i;j<N;j=j+k)
{
str[c++]=a[j];
}
dp[0]=str[0];
for(int j=1;j<c;j++) //想的时候从后往前想,写的时候从前往后写
{
if(j==1)
dp[j]=Max(str[j],dp[0]);
else
dp[j]=Max(dp[j-2]+str[j],dp[j-1]);
}
count+=dp[c-1];
}
}
printf("%d",count);
return 0;
}