题目来源,题目还算是比较简单,都是acm的基础题目,但是好久没有做题了啊,感觉有点吃力,脑子有点转不动了,以此告诫自己
做完之后回头来看,其实每一道题都可以找规律找到做法,很巧妙的做出来,可以不使用非常高深的做法,复杂度也不用优化到极致
第一题:大富翁游戏
大富翁游戏,玩家根据骰子的点数决定走的步数,即骰子点数为1时可以走一步,点数为2时可以走两步,点数为n时可以走n步。求玩家走到第n步(n<=骰子最大点数且是方法的唯一入参)时,总共有多少种投骰子的方法
题解:
数据量小到极致,6都告诉你了,你花两分钟把前面算出来就完了对不?完了还发现有规律
#include<bits/stdc++.h>
int a[]={1,2,4,8,16,32};
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
printf("%d\n",a[n-1]);
return 0;
}
第二题:拼凑钱币
给你六种面额 1、5、10、20、50、100 元的纸币,假设每种币值的数量都足够多,编写程序求组成N元(N为0~10000的非负整数)的不同组合的个数。
题解:
牛客网本题的一个解释很详细了,先看下图再看下一行的个人理解
这里一个可能难想到的一个点就是dp[j-money[i]]
,这个怎么理解呢:假设任意面值的纸币做为最小面值的时候,都是从1开始累加的
例如:一块钱是最小的时候(本身确实是最小的),很容易看得出是所有数值金额都只有一种拼凑方法
五块钱的时候:5,10,15,20…..也都是一样的,以此类推。
动态规划的思想之一就是把所有东西都等同看待,然后状态转移方程就很容易写出来了
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define maxn 10005
LL dp[maxn];
int money[]={1,5,10,20,50,100};
int main()
{
int n;
while(scanf("%d",&n) != EOF) {
memset(dp, 0, sizeof(dp));
dp[0] = 1;
for(int i = 0;i < 6; i++) {
for(int j = money[i]; j <= n; j++)
dp[j] += dp[j - money[i]];
}
printf("%lld\n",dp[n]);
}
return 0;
}
第三题:最大矩形面积
给定一组非负整数组成的数组h,代表一组柱状图的高度,其中每个柱子的宽度都为1。 在这组柱状图中找到能组成的最大矩形的面积(如图所示)。 入参h为一个整型数组,代表每个柱子的高度,返回面积的值
题解:
一种直接暴力,n*n的复杂度
一种利用单调栈的做法
#include <bits/stdc++.h>
using namespace std;
#define maxn 10005
typedef long long LL;
LL a[maxn];
int main()
{
int n;
while(scanf("%d",&n) != EOF) {
for(int i = 1; i <= n; i++)
scanf("%lld",&a[i]);
LL ans=a[1];
for(int i = 1; i <= n; i++) {
LL min_h=a[i];
for(int j = i+1; j <= n; j++) {
min_h = min(min_h, a[j]);
ans = max(ans, (j-i+1)*min_h);
}
}
printf("%lld\n", ans);
}
return 0;
}
第四题:最长公共连续子串
给出两个字符串(可能包含空格),找出其中最长的公共连续子串,输出其长度
题解:
这里一个没有注意的地方就是字符串里面还包含了空格
最长公共连续子串 和 最长公共子串不一样,一个连续一个不连续,不连续的也就多了一点点不一样的东西,大家可以网上找找看
本题状态转移方程因为是连续的所以就很简单啦:dp[i+1][j+1]=dp[i][j]+1;
#include<bits/stdc++.h>
using namespace std;
int main()
{
int dp[100][100];
char a[100],b[100];
while(gets(a)){
gets(b);
int a1=strlen(a);
int b1=strlen(b);
memset(dp,0,sizeof(dp));
int ans=0;
for(int i=0;i<a1;i++){
for(int j=0;j<b1;j++){
if(a[i]==b[j])
dp[i+1][j+1]=dp[i][j]+1;
ans=max(ans,dp[i+1][j+1]);
}
}
printf("%d\n",ans);
}
return 0;
}