动态规划(一)

在复习动态规划时发现了几道有趣的题,与大家分享一下!

目录

题目一

题目描述

输入输出样例

 分析题意

题目二

题目描述

输入格式

输出格式

输入输出样例

分析题意

代码:

课后习题:

总结

注释


题目一

题目描述

奶牛们开始了新的生意,它们的主人约翰想知道它们到底能做得多好。这笔生意已经做了N(1≤N≤100,000)天,每天奶牛们都会记录下这一天的利润Pi(-1,000≤Pi≤1,000)。

约翰想要找到奶牛们在连续的时间期间所获得的最大的总利润。(注:连续时间的周期长度范围从第一天到第N天)。

请你写一个计算最大利润的程序来帮助他。

本题链接

输入输出样例

输入 #1

7 
-3 
4 
9 
-2 
-5 
8 
-3 

输出 #1

14 

 分析题意

  这是一道最大连续子序列(子串),还是一道标准例题,掌握动态转移方程就可以解出来了。

  方程如下:

	if(b[i-1]>0){
		b[i]=b[i]+b[i-1];
	}

判断是否大于零,否则没必要去记录下来(最大)。

代码就呈现给大家:

#include<bits/stdc++.h>
using namespace std;
int a,b[100005],ans=-0x3f3f3f3f3f3f;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	cin>>a;
	for(int i=1;i<=a;i++){
		cin>>b[i];
	}
	for(int i=1;i<=a;i++){
		if(b[i-1]>0){
			b[i]=b[i]+b[i-1];
		}
	}
	for(int i=1;i<=a;i++){	
		if(b[i]>ans){
			ans=b[i];
		}
	}
	cout<<ans;
}

注意:整个数列也可以都是负数,所以记录数组ans要开的很小!

题目二

题目描述

FJ 到商场买工具。商场里有 K 种工具(1≤K≤100),价格分别为 1,2,…,K 元。FJ 手里有 N 元( 1≤N≤1000),必须花完。他有多少种购买方案呢?

本题链接

输入格式

一行两个整数 N,K。

输出格式

输出不同的购买方案数。

输入输出样例

输入 #1

5 3

输出 #1

5

分析题意

这是标准的背包问题(2),无穷版的背包问题,来尝试一下!

核心代码:

	for(int i=1;i<=a;i++){
		for(int j=i;j<=b;j++){
			f[j]+=f[j-i];
		}
	}

将现在状态与上一个状态加起来,就是结果。

代码如下:

#include<bits/stdc++.h>
using namespace std;
long long a,b,c,ans=0,Max;
long long f[100005];
int main(){
	cin>>b>>a;
	f[0]=1;
	for(int i=1;i<=a;i++){
		for(int j=i;j<=b;j++){
			f[j]+=f[j-i];
		}
	}
    cout<<f[b];
	return 0;
}

可是就只有70分

看了看优秀的题解 

发现要用一些技巧(要用__int128):

__int128 f[10001];
void write(__int128 x){
    if(x>9) write(x/10);
    putchar(x%10+'0');
}

这样就能AC了!

代码:

#include<bits/stdc++.h>
using namespace std;
long long a,b,c,ans=0,Max;
__int128 f[10001];
void write(__int128 x){
    if(x>9) write(x/10);
    putchar(x%10+'0');
}
int main(){
	cin>>b>>a;
	f[0]=1;
	for(int i=1;i<=a;i++){
		for(int j=i;j<=b;j++){
			f[j]+=f[j-i];
		}
	}
	write(f[b]);
	return 0;
}

课后习题:

easy

总结

dp看起来不难,但要发现动态转移方程要有良好的思维,还要进行大量的验证,最后抓住要点就可以啦!

注释

冷知识:int 大小受电脑字长影响,早期电脑通常为16位,那么 int最大值 为:2^(16-1)-1;好一点的电脑为32位,那么 int最大值 为:2^(32-1)-1。

现在最差的电脑也有32位,一般为64位,绝大多数情况默认64位。

即目前 int最大值 皆为2^(32-1)-1,不会更大。

long long 最大值:2^(64-1)-1【不可改变】 

__int128 大小:2^(128-1)-1 【不可改变】

经作者实测,这样 __int128 的精确范围是:
−170141183460469231731687303715884105728−170141183460469231731687303715884105728 ~ 170141183460469231731687303715884105727

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值