动态规划的几个简单例题

洛谷P1002 [NOIP2002 普及组] 过河卒

题目描述

棋盘上 AA 点有一个过河卒,需要走到目标 BB 点。卒行走的规则:可以向下、或者向右。同时在棋盘上 CC 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。

棋盘用坐标表示,AA 点 (0, 0)(0,0)、BB 点 (n, m)(n,m),同样马的位置坐标是需要给出的。

现在要求你计算出卒从 AA 点能够到达 BB 点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。

输入格式

一行四个正整数,分别表示 BB 点坐标和马的坐标。

输出格式

一个整数,表示所有的路径条数。

输入输出样例

输入 #1复制

6 6 3 3

输出 #1复制

6

说明/提示

对于 100 \%100% 的数据,1 \le n, m \le 201≤n,m≤20,0 \le0≤ 马的坐标 \le 20≤20。

【题目来源】

NOIP 2002 普及组第四题

#include<bits/stdc++.h>
using namespace std;
long long a[30][30];
//long long b[30][30];
int main(){
	int c[9]={1,-1,-1,3,3,0,0,2,2};
	int d[9]={1,0,2,0,2,-1,3,3,-1};
	long long n;
	//long long a[30][30]={0};
	int x1,x2,y1,y2;
	cin>>x2>>y2>>x1>>y1;
	for(int i=0;i<9;i++){
		if(x1+c[i]<1 || y1+d[i]<1)
		continue;
		a[x1+c[i]][y1+d[i]]=-1;
	}
	a[1][1]=1;
	for(int i=1;i<=x2+1;i++){
		for(int j=1;j<=y2+1;j++){
			if(a[i][j]==-1)
			a[i][j]=0;
			else{
				a[i][j]+=a[i-1][j]+a[i][j-1];
			}
		}
	}
	cout<<a[x2+1][y2+1];
	return 0;
}

洛谷P1164 小A点菜

题目背景

uim 神犇拿到了 uoi 的 ra(镭牌)后,立刻拉着基友小 A 到了一家……餐馆,很低端的那种。

uim 指着墙上的价目表(太低级了没有菜单),说:“随便点”。

题目描述

不过 uim 由于买了一些书,口袋里只剩 MM 元 (M \le 10000)(M≤10000)。

餐馆虽低端,但是菜品种类不少,有 NN 种 (N \le 100)(N≤100),第 ii 种卖 a_iai​ 元 (a_i \le 1000)(ai​≤1000)。由于是很低端的餐馆,所以每种菜只有一份。

小 A 奉行“不把钱吃光不罢休”,所以他点单一定刚好把 uim 身上所有钱花完。他想知道有多少种点菜方法。

由于小 A 肚子太饿,所以最多只能等待 11 秒。

输入格式

第一行是两个数字,表示 NN 和 MM。

第二行起 NN 个正数 a_iai​(可以有相同的数字,每个数字均在 10001000 以内)。

输出格式

一个正整数,表示点菜方案数,保证答案的范围在 int 之内。

输入输出样例

输入 #1复制

4 4
1 1 2 2

输出 #1复制

3
#include<bits/stdc++.h>
using namespace std;
int a[120],b[120][12000];
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
	cin>>a[i];
}
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
      {
          if(j==a[i]){
		  b[i][j]=b[i-1][j]+1;
	}
          if(j>a[i]){
		   b[i][j]=b[i-1][j]+b[i-1][j-a[i]];
	}
          if(j<a[i]) {
	     b[i][j]=b[i-1][j];
	 }
      }
    cout<<b[n][m];
    return 0;
}

牛客清楚姐姐学01背包(Easy Version)

题目描述 
本题有对应的hard version,区别仅在于数据范围,见输入描述,保证easy version的测试用例集是hard version的子集。
请确保在尝试本题时了解动态规划中01背包的相关内容。
如不了解动态规划或者01背包算法,可以到oiwiki进行学习了解后再尝试本题。
动态规划:https://oi-wiki.org//dp/
01背包:https://oi-wiki.org//dp/knapsack/#0-1-%E8%83%8C%E5%8C%85

清楚姐姐最近学会了01背包,01背包是背包问题中最简单的问题。

01背包的约束条件是给定几种物品,每种物品有且只有一个,并且有权值和体积两个属性。在01背包问题中,因为每种物品只有一个,对于每个物品只需要考虑选与不选两种情况。

如果不选择将其放入背包中,则不需要处理。如果选择将其放入背包中,由于不清楚之前放入的物品占据了多大的空间,需要枚举将这个物品放入背包后可能占据背包空间的所有情况。

现在清楚姐姐有NN个蝴蝶结,第ii个蝴蝶结的体积为w_{i}w 
i

 ,好看程度为v_{i}v 
i

 ,她准备了一个容量大小为MM的包包。她可以从这NN个蝴蝶结中任选若干个放入背包,但是所选蝴蝶结的体积总和不能大于背包的容量MM,清楚姐姐想要让所选蝴蝶结的好看程度总和最大化。

她运用自己刚刚学会的01背包知识,快速算出了她能用她的包包装下蝴蝶结好看程度总和的最大值。

现在清楚姐姐有了一个新的问题,我们定义原问题的答案,即所选蝴蝶结好看程度总和的最大值为Val_{max}Val 
max

 。

定义从这NN个蝴蝶结中去掉第ii个蝴蝶结后,从剩余N-1N−1个蝴蝶结中任选若干个放入背包,所选蝴蝶结好看程度总和的最大值为Val'_{i}Val 
i


 。

若Val'_{i}<Val_{max}Val 
i


 <Val 
max

 ,则称第ii个蝴蝶结为一个“必选蝴蝶结”。

清楚姐姐现在获得了调整蝴蝶结好看程度的机会,她想要知道,对于第ii个蝴蝶结,在它初始好看程度的基础上,再加上多少,该蝴蝶结就能够成为一个“必选蝴蝶结”。
输入描述:
第一行输入两个正整数N,M(1 \leq N,M \leq 100)N,M(1≤N,M≤100)。
接下来NN行,每行输入两个正整数w_i,v_i(1 \leq w_i \leq M, v_i \leq 10^9)w 
i

 ,v 
i

 (1≤w 
i

 ≤M,v 
i

 ≤10 
9
 )表示每个蝴蝶结的体积以及好看程度
输出描述:
输出NN行,每行一个整数,第ii行表示在它初始好看程度的基础上,再加上多少,该蝴蝶结就能够成为一个“必选蝴蝶结”。特别的,如果该蝴蝶结已经是一个“必选蝴蝶结”,则输出00。
示例1
输入
复制
4 100
100 100
99 10
1 2
5 5
输出
复制
0
89
89
94
示例2
输入
复制
3 1
1 100
1 100
1 100
输出
复制
1
1
1
说明
注意只有当Val'_{i}<Val_{max}Val 
i


 <Val 
max

 时,才称其为“必选蝴蝶结”,与原本的最大值完全相等时说明该蝴蝶结的好看程度还需要再加上11点。

#include<bits/stdc++.h>
using namespace std;
long long zui[2000];
int main(){
	long long v,n,a[2000],b[2000],g=0,l[2000],h;
	cin>>n>>v;
	for(int j=0;j<n;j++){
		cin>>a[j]>>b[j];
		for(int i=v;i>=a[j];i--){
			zui[i]=max(zui[i],zui[i-a[j]]+b[j]);
		}
	}
	 h=zui[v];
	while(g<n){
			for(int i=0;i<=v;i++){
			zui[i]=0;
		}
	for(int j=0;j<n;j++){
		if(j==g)
		continue;
		for(int i=v;i>=a[j];i--){
			zui[i]=max(zui[i],zui[i-a[j]]+b[j]);
		}
	}
	if(zui[v]<h)
		cout<<0<<'\n';
		else{
				l[g]=v-a[g];
	cout<<h-zui[l[g]]+1-b[g]<<'\n';
		}
	g++;
}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值