2019年4月3日

总结

就就如同老师在上课的时候讲的,dp要熟练,就是要多做题,见的多了,见到题也就知道具体的思路了。要是遇见一个从来没有出过的类型的题,无论谁首先都会是一脸懵。
所以今天我们继续来搞题。

例题

输入一串字符,有大小写,输入大写时可以用shift或者大写锁定,求输入这串字符最少要敲几次键盘。

例子

The string “Pirates”, can type this way, Shift, p, i, r, a, t, e, s, the answer is 8.
The string “HDUacm”, can type this way, Caps lock, h, d, u, Caps lock, a, c, m, the answer is 8
The string "HDUACM", can type this way Caps lock h, d, u, a, c, m, Caps lock, the answer is 8

对于这个题目,我想了好久,没有想出用dp怎么做,之后用模拟做的,但是效果吗。。。。
之后上网查了题解才明白过来。
这个题目最重要的是大写锁定的状态。
核心代码

	定义一个二维函数,dp表示大写锁定那个键的状态
	
	dp[0][i]:大写锁定是关闭
    	dp[1][i]:大写锁定是开启
    	
	if(s[i] >= 'a' && s[i] <= 'z')
	dp[0][i] = min(dp[0][i - 1] + 1, dp[1][i - 1] + 2);
	//本次操作完的状态是小写,当上次的状态为小写时,则按字母即可
          //当上次的状态为大写时,则关灯再按字母
          dp[1][i] = min(dp[0][i - 1] + 2, dp[1][i - 1] + 2);
·	//本次操作完的状态是大写,当上次的状态为小写时,则先开灯,再按字母;
         //当上次的状态为大写时,则直接按按字母```
	if(s[i]<='Z'&&s[i]>='A')//原理同上
	dp[0][i] = min(dp[0][i - 1] + 2, dp[1][i - 1] + 2);
	dp[1][i] = min(dp[0][i - 1] + 2, dp[1][i - 1] + 1);

全部代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;
const int MX = 105;
char s[MX];
int dp[2][MX];
int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%s", s + 1);
        memset(dp, 0, sizeof(dp));
        dp[0][0] = 0;
        dp[1][0] = 1;
        for(int i = 1; i <= strlen(s + 1); i++)
        {
            if(s[i] >= 'a' && s[i] <= 'z')
            {
                dp[0][i] = min(dp[0][i - 1] + 1, dp[1][i - 1] + 2);
                dp[1][i] = min(dp[0][i - 1] + 2, dp[1][i - 1] + 2);
            }
            else if(s[i] >= 'A' && s[i] <= 'Z')
            {
                dp[0][i] = min(dp[0][i - 1] + 2, dp[1][i - 1] + 2);
                dp[1][i] = min(dp[0][i - 1] + 2, dp[1][i - 1] + 1);
            }
        }
        cout<<min(dp[0][strlen(s + 1)], dp[1][strlen(s + 1)] + 1)<<endl;            //最后要关闭标记,所以若是标记开启,还要额外加一
    }
    return 0;
}
求因子只有2,3,5,7的数,并输出第x个。

这和求丑数差不多(就是多了一个7)。
核心代码

int i;
	number[1] = 1;
	int a;
	int b;
	int c;
	int d;
	int p1 = 1;
	int p2 = 1;
	int p3 = 1;
	int p4 = 1;
	for (i = 2; i <= maxn; ++i) {
		//从符合要求的数中找到最小的那个数作为目前number数
		number[i] = min(min(na = humber[pos1] * 2,nb = humber[pos2] * 3),
						min(nc = humber[pos3] * 5, nd = humber[pos4] * 7));
		if (number[i] == a) {//如果选择了这个因子,则将起索引向后移一位
			p1++;
		}
		if (nmber[i] == b) {
			p2++;
		}
		if (number[i] == c) {
			p3++;
		}
		if(number[i] == d){
			p4++;
		}
	}

感悟

在遇到了瓶颈。。。。。
感觉做了不少题,见到题还是不能一下子搞出思路来。
或者有了思路但是怎么搞都是WA。
丝毫没有成就感。
C++类那边也是似懂非懂。
自闭了。
算了,继续做吧。
指不定哪天能顿悟(笑)。

猜你喜欢

转载自blog.csdn.net/qq_17679843/article/details/89005991