假期训练五(poj-1077bfs+康拓展开,hdu-2577dp)

题目一:传送门

思路:主要是找到状态,

考虑字母有两种状态,大写和小写,

从小写变为大写的变化方式有两种:保持cap状态,或者按住shift键;

从小写变为大写也有一种变化方式:按住shift键;

看起来很乱,但是主要就是是否为cap状态,shift可以看做多按一次键,

不能算作状态,所以一个字母就两个状态,大写键开启,或不开启。

由此建立一个二维数组dp[i][j],i表示节点位置;j表示状态,有0,1两种,表示大写键开启或不开启。

然后就是从0--len依次循环更新状态就行了,注意最终状态是大写键关闭。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 120;
const int INF = 9999999;
char str[maxn];
int dp[maxn][5],a[maxn];
int MIN(int x,int y)
{
    return x<y?x:y;
}
int main(void)
{
    int t,fg,i,len,cnt,j;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s",str);
        len=strlen(str);
        dp[0][0]=0,dp[0][1]=1;
        for(i=0;i<len;i++)
        {
            if(str[i]>='a'&&str[i]<='z')
            {
                dp[i+1][0]=MIN(dp[i][0]+1,dp[i][1]+2);
                dp[i+1][1]=MIN(dp[i][0]+2,dp[i][1]+2);
            }
            else
            {
                dp[i+1][0]=MIN(dp[i][0]+2,dp[i][1]+2);
                dp[i+1][1]=MIN(dp[i][0]+2,dp[i][1]+1);
            }
        }
        printf("%d\n",MIN(dp[len][1]+1,dp[len][0]));
    }
    return 0;
} 
View Code

题目二:传送门

思路:bfs+康托展开

参考文章:传送门

(1)将二维坐标用以为数组存储,每次只要进行行列变换就行了;

(2)每次交换两个坐标的值,然后再重新算出这个序列在全排列中的位置;

(3)x可以设为9,利用康拓展开每次返回当前序列在1-9全排列的位置,截止的标志是statu==1;

(4)每次记录变换的方向和前一个位置。

猜你喜欢

转载自www.cnblogs.com/2018zxy/p/10255697.html