01背包与对决匹配(动态规划)

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;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值