zoukankan      html  css  js  c++  java
  • DP Review 1

    DP Review 1

    这个dp啊,我就是直接用题目来说了

    USACO3.1.2 总分

    洛谷上面的链接
    这一道题是一道比较容易看出来的题目,就是设f[n]代表时间为n的时候的最大的分数,然后就枚举第几个种类以及时间就可以了(就是背包问题啊)

    Code

    #include<bits/stdc++.h>
    #define maxn 10002
    #define Int64 long long
    using namespace std;
    
    int M,N;//时间,种类
    int t[maxn],s[maxn];//耗时,分数
    Int64 f[maxn];
    
    int main(){
    	scanf("%d%d",&M,&N);
    	for(int i=1;i<=N;i++){
    		scanf("%d%d",&s[i],&t[i]); 
    	}
    	
    	memset(f,0,sizeof(f));
    	
    	for(int i=1;i<=N;i++){
    		for(int j=1;j<=M;j++){
    			if(j>=t[i]){
    				f[j]=max(f[j],f[j-t[i]]+s[i]);
    			}
    		}
    	}
    	cout<<f[M];
    	
    	return 0;
    } 
    

    逃亡的准备

    Description

    在《Harry Potter and the Deathly Hallows》中,Harry Potter他们一起逃亡,现在有许多的东西要放到赫敏的包里面,但是包的大小有限,所以我们只能够在里面放入非常重要的物品,现在给出该种物品的数量、体积、价值的数值,希望你能够算出怎样能使背包的价值最大的组合方式,并且输出这个数值,赫敏会非常地感谢你。

    Input

    第一行有2个整数,物品种数n和背包装载体积v。  第 2 行到 n+1 行每行3个整数,为第i种物品的数量m、体积w、价值s。.

    Output

    仅包含一个整数,即为能拿到的最大的物品价值总和。

    Sample Input

    2 10
    3 4 3
    2 2 5
    

    Sample Output

    13
    

    Analysis

    这一道题啊,一眼就可以看出是一个多重背包问题所以说就可以写出核心的代码

    for(int i=1;i<=n;i++){
    		for(int j=v;j>=1;j--){
    			for(int k=1;k<=m[i];k++){
    				if(j>=c[i]*k){
    					f[j]=max(f[j],f[j-k*c[i]]+k*p[i]);
    			 	}
    			}
    		}
    	} 
    

    如果你把上面那一段交上去,毫无疑问,你就会TLE几个点
    为了优化,中间你应该写成

    if(j>=c[i]*k){
    	f[j]=max(f[j],f[j-k*c[i]]+k*p[i]);
    }
    	else break;
    

    因为既然都比C[i]*k小了,接着k还要继续增大,这不是浪费时间吗,
    那么我们就大胆而合理的AC了这道题
    这样就可以完美地解决超时的问题了啦

    最大约数和

    洛谷的链接

    Analysis

    这一道题根据题意,你首先要知道1~N和之间每一个数的约数的和,可以通过下面一个函数来解决

    inline void div(int x){
    
    	for(int i=2;i<=sqrt(x);i++){
    		if(!(x%i)){
    			factor_sum[x]+=(i+x/i);
    			if(i==sqrt(x))factor_sum[x]-=i;
    		}
    	}
    	factor_sum[x]++;
    	
    }
    //获取每一个数的约数和 
    

    然后呢,就需要dp了,这一个自己感觉是有点像是一个完全背包,但是这并不代表这是一个完全背包的题,我的意思是,在累加的过程中,你选择的累加的数是有无限多个,因此从前往后枚举就可以了

    for(int i=1;i<=n;i++){
    	for(int j=1;j<=i;j++){
    		factor_sum[i]=max(factor_sum[i],factor_sum[j]+factor_sum[i-j]);
    	}
    }
    

    想到了这些,就可以AC

  • 相关阅读:
    性能分析
    单例模式
    装饰者模式
    开发Chrome Extension截取你微博的帐号密码
    201703-3 markdown
    201612-3 权限查询
    201609-3 炉石传说
    201604-2 俄罗斯方块
    201604-3 路径解析
    201512-1 数位之和
  • 原文地址:https://www.cnblogs.com/perisino/p/10405796.html
Copyright © 2011-2022 走看看