B3635 硬币问题
题目描述
今有面值为 1、5、11 元的硬币各无限枚。
想要凑出 nn 元,问需要的最少硬币数量。
输入格式
仅一行,一个正整数 n。
输出格式
仅一行,一个正整数,表示需要的硬币个数。
输入输出样例
输入 #1
15
输出 #1
3
输入 #2
12
输出 #2
2
说明/提示
样例解释
对于样例数据 1,最佳方案是 15=5+5+5,使用到 3 枚硬币。
对于样例数据 2,最佳方案是 12=11 + 1,使用到 2 枚硬币。
数据规模与约定
对于100% 的数据,保证 n≤10^6。
解释:使用一维dp,就是在当前问题中寻找出他的子问题,找到最优解。
#include<iostream>
#include <vector>
#include <algorithm>
using namespace std;
int a[1000006];//定义a[i]为:凑出i元最少要a[i]个硬币
//这是一维dp
int main()
{
int n;
cin>>n;
a[0]=0;
a[1]=1;
a[5]=1;
a[11]=1;//根据题意初始化只有三种硬币,1,5,11
for(int i=2;i<=n;i++)//在凑出i元的时候,可以由凑出i-1元,i-5元,i-11元的硬币个数加上一个,那么就要找出这三种情况中的最小需要的硬币。
{
if(i-1>=0)//在寻找这三种凑硬币的个数是要注意,会在减去这三种硬币的时候出现负数,要进行判断。
{
a[i]=a[i-1]+1;
if(i-5>=0)
{
a[i]=min(a[i-1],a[i-5])+1;
if(i-11>=0)
{
a[i]=min(a[i-1],min(a[i-5],a[i-11]))+1;
}
}
}
}
cout<<a[n];
return 0;
}
B3636 文字工作
题目描述
机器猫要在电脑前打字。一共需要打 n 个字,但现在文档里只有一个字。
机器猫有两种操作可以做。假设现在已经有 x个字,机器猫可以选择:
- 往文档最后加一个字。字数变成 x+1。
- 把文档复制粘贴一遍。字数变成 2x。
问机器猫至少需要多少次操作,才能得到恰好 n个字。
输入格式
仅一行,一个正整数 n。
输出格式
仅一行,一个正整数,表示最少操作次数。
输入输出样例
输入 #1
16
输出 #1
4
输入 #2
5
输出 #2
3
说明/提示
样例解释
样例数据1,1→2→4→8→16,共 4 步。
样例数据2,1→2→4→5,共 3 步。
数据规模与约定
对于 100\%100% 的数据,n≤10^6。
#include<iostream>
#include <algorithm>
using namespace std;
int a[1000006];
int main()
{
int n;
cin>>n;
a[1]=0;//对dp数组进行初始化,题目说开始的时候已经有一个字了
for(int i=2;i<=n;i++)//根据题意建立状态转移方程式,得到i个字可以由两种方式得到,i-1和i/2个字加1
{
if(i%2==0)
{
a[i]=min(a[i-1],a[i/2])+1;
}
else
{
a[i]=a[i-1]+1;
}
}
// for(int i=1;i<=n;i++)
// {
// cout<<a[i]<<"\n";
// }
cout<<a[n];
return 0;
}
B3637 最长上升子序列
题目描述
这是一个简单的动规板子题。
给出一个由 nn(n≤5000) 个不超过 10^6的正整数组成的序列。请输出这个序列的最长上升子序列的长度。
最长上升子序列是指,从原序列中按顺序取出一些数字排在一起,这些数字是逐渐增大的。
输入格式
第一行,一个整数 nn,表示序列长度。
第二行有 nn 个整数,表示这个序列。
输出格式
一个整数表示答案。
输入输出样例
输入 #1
6 1 2 4 1 3 4
输出 #1
4
说明/提示
分别取出 1、2、3、4 即可。
#include<iostream>
#include <algorithm>
using namespace std;
int a[5003];
int c[5003];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
c[1]=1;
for(int i=2;i<=n;i++)//找状态转移方程式c[i]:在数组中a[i]中以第i个元素结尾的最长上升子序列
{
int t=0;
for(int j=1;j<i;j++)//在前j个元素中,找小于a[i]的以a[j]结尾的最大值,然后再加1。
{
if(a[i]>a[j])
{
t=max(c[j],t);
}
}
c[i]=t+1;
}
int max1=0;
for(int i=1;i<=n;i++)//找出最大值
{
max1=max(max1,c[i]);
}
cout<<max1;
return 0;
}