hdu3747 Download

题意很浅显,给定当前下载任务的已选状态和最终状态,可以当过单选,全选,反选等三个操作达成,问最少的操作数

分析:思维真的有很大的局限性,怎么就没想到去整理一下规律呢,一心只想着搜索,dp呀,虽然这俩方面都很水……

看了大牛的解释,我也跟着恍然大悟了……

View Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    char S[55],T[55];
    int i,j;
    int Min,count[4],n;
    while (scanf("%d",&n)!=EOF)
    {
        memset(count,0,sizeof(count));
        scanf("%s",S);
        scanf("%s",T);
        for (i = 0; i < n; i++)
        {
            if (S[i]!=T[i])
                count[0]++;    //记录不同的位,对直接改变这些位需要的操作
            else
                count[1]++;    //记录相同的位,反选一次后改变这些位
            if(T[i]=='0') count[2]++; //目标序列中0的位,就是不需要选择的TV,全选后复原这些位需要的操作
        }
        //count[0]就是直接点击选择需要的总操作次数
        count[1]++; 
        //count[1]为反选一次后再作选择总操作,增加一次反选操作
        count[2]++; 
        //count[2]是全选一次后取消选择总操作,count[2]为全选后取消选择需要的操作,增加一次全选操作
        count[3] = 2+n-(count[2]-1);
        //n-(count[2]-1)等于需要选择看的TV总数 ,再+2表示全选反选归零后重新选择的做法

       //count[0]直接选择是理所当然的做法。

       //其实关键是需要考虑到,对于全选和反选,都是只是做一次的,或者各做一次。

       //这个很容易可以证明,因为两次反选后对每一位来说,状态又回到原来的去,相当于多花费两次操作。

       //每次全选就等于回到到第一次的全选了。

       //全选之后反选归零。

       //其实联想到逻辑代数里的一些关系,还是挺直观的。。。为什么当时就没想到!!!!

        Min = count[0];

        for (i = 1; i < 4; i++)

            Min = (count[i]<Min?count[i]:Min);

        printf("%d\n",Min);

    }

    return 0;

}

代码来自此博客http://blog.sina.com.cn/s/blog_626631420100tjzv.html

posted @ 2012-04-17 21:11  枕边梦  阅读(185)  评论(0编辑  收藏  举报