题意很浅显,给定当前下载任务的已选状态和最终状态,可以当过单选,全选,反选等三个操作达成,问最少的操作数
分析:思维真的有很大的局限性,怎么就没想到去整理一下规律呢,一心只想着搜索,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; }