1.4 State machine model

State machine introduction:
Insert image description here

1.The big thief Ah Fu

Ah Fu is an experienced thief. Taking advantage of the dark moon and high wind, Ah Fu planned to ransack a shop on a street tonight.

There are NN in total on this streetThere are N stores, each of which has some cash.

Ah Fu learned from his prior investigation that only when he ransacked two adjacent shops at the same time would the alarm system on the street be activated, and then the police would swarm in.

As a thief who always commits crimes cautiously, Ah Fu is unwilling to take the risk of being chased by the police.

He wanted to know, how much cash could he get at most tonight without alerting the police?

Input format
The first line of input is an integer TTT , indicating a total ofTTT group of data.

For each subsequent set of data, the first line is an integer NNN , indicating that there areNNN stores.

The second line is NNN positive integers separated by spaces, representing the amount of cash in each store.

The amount of cash in each store does not exceed 1000 10001000

Output format
For each set of data, output one line.

The row contains an integer representing the amount of cash that Afu could obtain without alerting the police.

Data range
1 ≤ T ≤ 50, 1≤T≤50,1T50,
1 ≤ N ≤ 1 0 5 1≤N≤10^{5} 1N105

Input example:

2
3
1 8 2
4
10 7 6 14

Output sample:

8
24

Example explanation
For the first set of examples, Afu chose the second shop to steal, and the amount of cash he obtained was 8 88

For the second set of examples, Afu chose the 1st and 4th stores to steal, and the amount of cash obtained was 10 + 14 = 24 10+14=2410+14=24

1.1 Solution

Insert image description here

Insert image description here
Now consider only the state from the upper level instead of the state from the upper two levels

Decomposition state
Insert image description here
state machine model
Insert image description here
using DP analysis method + state machine

Insert image description here
Use the form of a state machine to separate states that are difficult to express

Idea 1
We can define an array as f [ ] f[]f[]

f [ i ] f[i] f [ i ] represents the maximum amount of cash that family i can get before robbery.

Then there are two situations for the robbery of our former i house:

The first case: do not steal the i-th store
, then f [ i ] = f [ i − 1 ] f[i]=f[i−1]f[i]=f[i1];

The second case: Stealing the i-th store
, then f [ i ] = f [ i − 1 ] + w [ i ] . f[i]=f[i−1]+w[i].f[i]=f[i1]+w[i].

w [ i ] w[i] w [ i ] represents the total cash in the i-th store)

Problems arising from idea 1:
If i − 1 i−1iStore 1 has been robbed, then if the store iiis robbedi family, that does not meet the requirements of the question.

then what should we do?

Correct method (Idea 2):

We define the f array as two-dimensional, that is, f [ ] [ ] f[][]f[][]

We use an array to store two situations: stealing or not stealing.

f [ i ] [ 0 ] f[i][0] f [ i ] [ 0 ] represents the maximum amount of cash that can be obtained without stealing the i-th store;
f [ i ] [ 1 ] f [i][1]f [ i ] [ 1 ] represents the maximum amount of cash that can be obtained by stealing the i-th store.

Then there will be three situations:
Insert image description here
explanation:

The red line in the picture is a feasible solution. You don’t need to grab the i − 1 i−1iNo. 1 , and I won’t grab thesecond oneHome i ;
you don’t need to grab thei − 1 i−1i1 , but grab theiii home.
You can grabi − 1 i−1i1 , but don’t grab theiii family;

Then we can get the state transition equation:

f[i][0] = max(f[i - 1][0], f[i - 1][1]);
f[i][1] = f[i - 1][0] + w[i];
1.2 Code implementation
#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 100010,INF = 0x3f3f3f3f;
int n;
int w[N],f[N][2];

int main()
{
    
    
    int T;
    scanf("%d",&T);
    while(T--)
    {
    
    
        scanf("%d",&n);
        for(int i = 1;i <= n;i++)   scanf("%d",&w[i]);
        f[0][0] = 0,f[0][1] = -INF;
        for(int i = 1;i <= n;i++)
        {
    
    
            f[i][0] = max(f[i - 1][0],f[i - 1][1]);
            f[i][1] = f[i - 1][0] + w[i];
        }
        printf("%d\n",max(f[n][0],f[n][1]));
    }
    
    return 0;
}

2. Stock Trading IV

Given a length of NNArray of N , iithin the arrayNumber i represents a given stock’s position atiiPrice for i day.

Design an algorithm to calculate the maximum profit you can make. You can complete kk at mostk transactions.

NOTE: You cannot participate in multiple trades at the same time (you must sell your previous shares before buying again). A buy and sell is combined into one transaction.

Input format
The first line contains the integer NNN andkk_k , represents the length of the array and the maximum number of transactions you can complete.

The second row contains NNN no more than10000 10000A positive integer of 10000 , representing the complete array.

Output format
Output an integer representing the maximum profit.

Data range
1 ≤ N ≤ 1 0 5 , 1≤N≤10^{5},1N105,
1 ≤ k ≤ 100 1≤k≤100 1k100
input example 1:

3 2
2 4 1

Output sample 1:

2

Input example 2:

6 2
3 2 6 5 0 3

Output sample 2:

7

Example explanation
Example 1: Buy on the 1st day (stock price = 2) and sell on the 2nd day (stock price = 4). The profit from this transaction = 4-2 = 2 .

Example 2: Buy on the 2nd day (stock price = 2) and sell on the 3rd day (stock price = 6). The profit from this transaction = 6-2 = 4. Then, buy on the 5th day (stock price = 0) and sell on the 6th day (stock price = 3). The profit from this transaction = 3-0 = 3. Total profit 4+3 = 7.

2.1 Solution

Insert image description here
Initialization: f[0][j][0] = 0, the rest -INF, because the 0stock must be out of stock, the transfer must start from this position to be effective.

Note:
In the process of the state machine here, for each stock, you either buy or sell it. It cannot be said that you buy it and then sell it directly at the same point. This is not in line with the state machine model. Therefore, the above transfer equation can There will be questions.
Why can't the state transfer equation be the following code? That is, a transaction is only counted when selling. The original code is only counted as a transaction when buying.

f[i][j][0] = max(f[i - 1][j - 1][1] + w[i], f[i - 1][j][0]);
f[i][j][1] = max(f[i - 1][j][0] - w[i], f[i - 1][j][1]);

After all, we have to return to the starting point of the state transition. The first stock only has two operations: buying and not buying. It must not be two operations: selling and not selling. Therefore, if the first stock is bought, it must be carried out according to the One transaction is processed . Otherwise, if the first stock purchase is not treated as one transaction, it means that the sale of the first stock is considered a transaction, which means that another stock was purchased before the first stock was sold. , obviously contradictory.

2.2 Code implementation
#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 100010,M = 110,INF = 0x3f3f3f3f;

int n,m;
int w[N];
int f[N][M][2];//状态

int main()
{
    
    
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i++)   scanf("%d",&w[i]);   
    
    memset(f,-0x3f,sizeof f);
    for(int i = 0;i <= n;i++)    f[i][0][0] = 0;
   
    for(int i = 1;i <= n;i++)
        for(int j = 1;j <= m;j++)
        {
    
    
            f[i][j][0] = max(f[i - 1][j][0],f[i - 1][j][1] + w[i]);
            f[i][j][1] = max(f[i - 1][j][1],f[i - 1][j - 1][0] - w[i]);
        }
    
    //枚举一下进行多少次交易
    int res = 0;
    //最后手中一定没货
    for(int i = 0;i <= m;i++)   res = max(res,f[n][i][0]);
    printf("%d",res);
    return 0;
}

3. Stock trading V

Given a length of NNArray of N , iithin the arrayNumber i represents a given stock’s position atiiPrice for i day.

Design an algorithm to calculate the maximum profit. You can complete as many transactions as possible (buy and sell a stock multiple times) subject to the following constraints:

  • You cannot participate in multiple trades at the same time (you must sell your previous shares before buying again).
  • After selling the stock, you cannot buy the stock the next day (i.e. the freeze period is 1 day).

Input format
The first line contains the integer NNN , represents the array length.

The second row contains NNN no more than10000 10000A positive integer of 10000 , representing the complete array.

Output format
Output an integer representing the maximum profit.

Data range
1 ≤ N ≤ 1 0 5 1≤N≤10^{5}1N105Input
sample:

5
1 2 3 0 2

Output sample:

3

Example explanation
The corresponding transaction status is: [Buy, Sell, Freeze Period, Buy, Sell], the first transaction can obtain profit 2 − 1 = 1 2-1 = 121=1 , the profit from the second transaction is2 − 0 = 2 2-0 = 220=2 , total profit1 + 2 = 3 1+2 = 31+2=3

3.1 Solution

Insert image description here
Initialization: f[0][2] = f[0][1] = 0,f[0][0] = -INF, because the 0th stock must be out of stock, and the transfer must start from this position to be effective.

3.2 Code implementation
#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 100010,INF = 0x3f3f3f3f;

int n;
int w[N];
int f[N][3];

int main()
{
    
    
    scanf("%d",&n);
    for(int i = 1;i <= n;i++)   scanf("%d",&w[i]);
    f[0][0]  = - INF;
    f[0][2] = f[0][1] = 0;
    
    for(int i = 1;i <= n;i++)
    {
    
    
        f[i][0] = max(f[i - 1][0],f[i - 1][2] - w[i]);
        f[i][1] = f[i - 1][0] + w[i];
        f[i][2] = max(f[i - 1][1],f[i - 1][2]);
    }
    
    cout << max(f[n][1],f[n][2]) <<endl;
    
    return 0;
}

4. Design a password

You now need to design a password SSS S S S needs to satisfy:

S S The length of S isNNN
S S S contains only lowercase English letters;
SSS does not contain the substringTTT ;
for example:abc abcabc a b c d e abcde ab c d eabcde abcdesubstring of ab c d e , abd abdab d is notabcde abcdesubstring of ab c d e .

How many different passwords can meet the requirements?

Since the answer will be very large, please output the answer modulo 1 0 9 + 7 10^{9}+7109+The remainder of 7 .

Input format:
Enter the integer NN in the first lineN , represents the length of the password.

The second line enters the string TTT T T T contains only lowercase letters.

Output format:
Output a positive integer, indicating the total number of solutions modulo 1 0 9 + 7 10^{9}+7109+The result after 7 .

Data range
1 ≤ N ≤ 50, 1≤N≤50,1N50,
1 ≤ ∣ T ∣ ≤ N , ∣ T ∣ 1≤|T|≤N,|T| 1TN , T isTTThe length of T.

Input example 1:

2
a

Output sample 1:

625

Input example 2:

4
cbc

Output sample 2:

456924
4.1 Solution to the problem (this problem is more troublesome and combines automata and KMP)

Insert image description here
Insert image description here

Why is such a state representation feasible?
Because SSThe nnthin S arrayThere are 26 26 in n digits26 lowercase letters, matching inTTThe position in T must exist (because there is no match, the matched position is0 00 ),
so put allf [ n ] [ 0 m − 1 ] f[n][0~m-1]f[n][0 m1 ] Add up to the total number of plans

4.2 Code implementation
#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

const int N=55,mod=1e9+7;

int f[N][N],ne[N];
char str[N];//子串

int main()
{
    
    
    int n,m;
    cin>>n>>str+1;
    m=strlen(str+1);

    for(int i=2,j=0;i<=m;i++)//求出ne数组(kmp模板)
    {
    
    
        while(j&&str[j+1]!=str[i]) j=ne[j];
        if(str[j+1]==str[i]) j++;
        ne[i]=j;
    }

    f[0][0]=1;//已经匹配了0位,且匹配的子串的位置是0时的方案数为1;(初始化)
    for(int i=0;i<n;i++)//枚举密码位
     for(int j=0;j<m;j++)//把第i位密码匹配到的子串位置都枚举一遍
     //j表示第i位密码匹配到的位置,因为不能包含子串,所以不能匹配到m这个位置
      for(char k='a';k<='z';k++)//把第i+1所有可能的字母都枚举一遍
       {
    
    
           //匹配过程:寻找当第i+1的位置是k时,并且密码已经生成了第i位,匹配的子串的位置是j时,能跳到哪个位置
           int u=j;
           while(u&&str[u+1]!=k) u=ne[u];
           if(str[u+1]==k) u++;

           if(u<m) f[i+1][u]=(f[i+1][u]+f[i][j])%mod;
           //因为是从f[i][j](i+1的位置为k)跳到f[i+1][u]这个位置,所以f[i+1][u]=f[i+1][u]+f[i][j];
           /*
           注:可能存在重边,因为j不同但ne[j]是相同的,并且k是相同的,所以此时
           f[i][j1]和f[i][j2]跳到的位置是一样的(k相同,ne[j1]=ne[j2])
           */
       }

    int res=0;
    for(int i=0;i<m;i++) res=(res+f[n][i])%mod;
    //将所有的方案数加起来即为总方案数
    printf("%d",res);

    return 0;
}

Guess you like

Origin blog.csdn.net/m0_51366201/article/details/132611475