day14(每日一题)
🎉前言:每日更新!不断更!,周内一天一题.周末算法精析
✨更新地址:Royeblog
🎆🎆第十一届国赛javaB 试题D: 本质上升序列
🎉题目链接:题号1021
✨简单描述题目:
小蓝特别喜欢单调递增的事物。
在一个字符串中,如果取出若干个字符,将这些字符按照在字符串中的顺序排列后是单调递增的,则成为这个字符串中的一个单调递增子序列。
例如,在字符串 lanqiao 中,如果取出字符 n 和 q,则 nq 组成一个单调递增子序列。类似的单调递增子序列还有 lnq、i、ano 等等。 小蓝发现,有些子序列虽然位置不同,但是字符序列是一样的,例如取第二个字符和最后一个字符可以取到 ao,取最后两个字符也可以取到 ao。小蓝认为他们并没有本质不同。 对于一个字符串,小蓝想知道,本质不同的递增子序列有多少个? 例如,对于字符串
lanqiao,本质不同的递增子序列有 21 个。它们分别是
l、a、n、q、i、o、ln、an、lq、aq、nq、ai、lo、ao、no、io、lnq、anq、lno、ano、aio。
import java.util.Arrays;
public class D本质上升序列 {
public static void main(String[] args) {
String s="tocyjkdzcieoiodfpbgcncsrjbhmugdnojjddhllnofawllbhfiadgdcdjstemphmnjihecoapdjjrprrqnhgccevdarufmliqijgihhfgdcmxvicfauachlifhafpdccfseflcdgjncadfclvfmadvrnaaahahndsikzssoywakgnfjjaihtniptwoulxbaeqkqhfwl";
char[] arr=s.toCharArray();
int[] dp=new int[arr.length];
Arrays.fill(dp,1);
for (int i = 1; i < arr.length; i++) {
for (int j = 0; j < i; j++) {
if (arr[j]==arr[i]) {
dp[i]=dp[i]-dp[j];
}
if (arr[j]<arr[i]){
dp[i]=dp[i]+dp[j];
}
}
}
int ans=0;
for (int i = 0; i < dp.length; i++) {
ans+=dp[i];
}
System.out.println(ans);
}
}
举个例子 1 2 2
dp[i]表示第i个能有几个递增序列,重点介绍两个相同时得减去,题目说了得"本质"不同😎
🎆🎆第十一届国赛javaB 试题E: 玩具蛇
🎉题目链接:题号1022
✨简单描述题目:
小蓝有一条玩具蛇,一共有 16节,上面标着数字 1 至 16。每一节都是一个正方形的形状。相邻的两节可以成直线或者成 90 度角。
小蓝还有一个 4 × 4 的方格盒子,用于存放玩具蛇,盒子的方格上依次标着字母 A 到 P 共 16个字母。
小蓝可以折叠自己的玩具蛇放到盒子里面。他发现,有很多种方案可以将玩具蛇放进去。
public class E玩具蛇 {
static int[][] vis;
static int ans;
static int[] x;
static int[] y;
public static void main(String[] args) {
x= new int[]{0, 0, 1, -1};
y= new int[]{1, -1, 0, 0};
for (int i = 1; i < 5; i++) {
for (int j = 1; j < 5; j++) {
vis=new int[5][5];
dfs(i,j,1);
}
}
System.out.println(ans);
}
public static void dfs(int i,int j,int step){
vis[i][j]=1;
if (step==16){
ans++;
return;
}
for (int k = 0; k < x.length; k++) {
int indexx=i+x[k];
int indexy=j+y[k];
if (indexx>0&&indexx<5&&indexy>0&&indexy<5&&vis[indexx][indexy]==0){
step++;
dfs(indexx,indexy,step);
step--;
vis[indexx][indexy]=0;
}
}
}
}
dfs模板题,注意每次开完清空vis数组,也就是把定义vis写在循环里面😎
🎆🎆第十一届国赛javaB 试题F: 蓝肽子序列
🎉题目链接:题号1030
✨简单描述题目:
【问题描述】
L 星球上的生物由蛋蓝质组成,每一种蛋蓝质由一类称为蓝肽的物资首尾连接成一条长链后折叠而成。
生物学家小乔正在研究 L 星球上的蛋蓝质。她拿到两个蛋蓝质的蓝肽序列,想通过这两条蓝肽序列的共同特点来分析两种蛋蓝质的相似性。
具体的,一个蓝肽可以使用 11 至 55 个英文字母表示,其中第一个字母大写,后面的字母小写。一个蛋蓝质的蓝肽序列可以用蓝肽的表示顺序拼接而成。
在一条蓝肽序列中,如果选取其中的一些位置,把这些位置的蓝肽取出,并按照它们在原序列中的位置摆放,则称为这条蓝肽的一个子序列。蓝肽的子序列不一定在原序列中是连续的,中间可能间隔着一些未被取出的蓝肽。
如果第一条蓝肽序列可以取出一个子序列与第二条蓝肽序列中取出的某个子序列相等,则称为一个公共蓝肽子序列。
给定两条蓝肽序列,找出他们最长的那个公共蓝肽子序列的长度。
【输入格式】
输入两行,每行包含一个字符串,表示一个蓝肽序列。字符串中间没有空格等分隔字符。
其中有 ,两个字符串的长度均不超过 10001000。
【输出格式】
输出一个整数,表示最长的那个公共蓝肽子序列的长度。
【样例输入】LanQiaoBei LanTaiXiaoQiao
【样例输出】
2
最大运行时间:1s
最大运行内存: 128M
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class F蓝肽子序列 {
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
String s1 = bf.readLine();
String s2 = bf.readLine();
String replace1 = s1.replaceAll("[A-Z]", ",$0");
String replace2 = s2.replaceAll("[A-Z]", ",$0");
String[] split1 = replace1.split(",");
String[] split2 = replace2.split(",");
int[][] dp = new int[split1.length + 1][split2.length+ 1];
//dp[0][0]= 0;
for (int i = 1; i < split1.length; i++) {
for (int j = 1; j < split2.length; j++) {
if (split1[i].equals(split2[j])) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
System.out.println(dp[split1.length-1][split2.length-1]);
}
}
LCS模板题,就是每一个字符换成了特定的Aaa模式,String replace1 = s1.replaceAll(“[A-Z]”, “,$0”);学会这个就好😎