DP动态规划

1. 0-1背包问题

1)动态规划法

经典的01背包裸题一般都是这个方法很快敲出来的。

#include <iostream>
#include <algorithm>
#include <stdio.h>
using namespace std;
int w[35000],d[35000],dp[35000];
int main()
{
    int n,m; //n是物品个数,m是背包最大承重或者说容量
    while(scanf("%d%d",&n,&m)!=EOF) {
        for(int i=1;i<=n;i++)
            scanf("%d%d",&w[i],&d[i]);
            
        for(int i=1;i<=n;i++)
            for(int j=m;j>=w[i];j--)
                dp[j]=max(dp[j],dp[j-w[i]]+d[i]);
            
        printf("%d\n",dp[m]);
    }
    return 0;
}

前身:
这种方法我觉得是更好理解的,他是第一种方法的未优化空间版本,容易超空间…

#include <iostream>
#include <algorithm>
#include <cstdio>

using namespace std;

int N,W; //N物品个数,W承重或容量
int results[13500][13000];
int w[13500],v[13500]; //weight and value

int main(int argc, char *argv[]) {
	
	while(scanf("%d%d",&N,&W)!=EOF) {
		for(int i=1;i<=N;i++) 
			scanf("%d%d",&w[i],&v[i]);
		
		for (int i = 1; i <= N; i++)
			for (int j = 1; j <= W; j++) {
				
				if (j < w[i]) // 装不进去
				results[i][j] = results[i-1][j];
				
				else   // 容量足够
				results[i][j] = max( results[i-1][j],results[i-1][j-w[i]] + v[i] );
				
			}
		for(int i=0;i<=N;i++) {
			cout<<endl;
			for(int j=0;j<=W;j++)
				printf("%-4d ",results[i][j]);
		}
		
	}
	
}

2)分治法

同时也记录一下分治法,最小生成树-Kruskal(克鲁斯卡尔)算法的思想。有些问题会超时,毕竟是递归。

 int ks(int i, int c){ //i是物品个数,c是背包容量
    int result = 0;
    if (i == 0 || c == 0){
        // 初始条件
        result = 0;
    } else if(ws[i] > c){
        // 装不下该珠宝
        result = ks(i-1, c);
    } else {
        // 可以装下
        int tmp1 = ks(i-1, c);
        int tmp2 = ks(i-1, c-ws[i]) + vs[i];
        result = max(tmp1, tmp2);
    }
    return result;
}

2.完全背包问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值