1152. False Mirrors URAL 解题报告

来源:互联网 发布:暴风影音windows版 编辑:程序博客网 时间:2024/04/28 04:12

1152. False Mirrors URAL 解题报告

这道题的大体意思是,一个n个阳台,每个阳台上有多个怪物,a1,a2,a3……an;   然后一个人可以shoot,射中一个阳台,那么这个阳台和左右两边相邻的阳台上的怪物都会死掉,剩下的不死的怪物就会反击,每只反击一个Unit的伤害,问最小的伤害是多少?   a1和an是相邻的!       假如a1和a 5之间阳台都被毁坏了,也不算数相邻的!
 这个题在URAL上被归为DP,但是DP的算法实在想不出来,看着数据不大,n最大20,而且看别人解题报告说是DFS就可以,其实是穷举的思想,外加优化,其实就是看看这个比最优解大还是小,有没有继续DFS的必要了……      

但是这个题折磨了我一上午,为什么呢?!  既然要递归,也可定要有回溯,我设置了一个vis数组,标志访问, 然后在0和n+1出弄了两个哨兵,自以为很巧妙,实际操作却把我难住了,因为这样就把a1,a0  捆绑在一起了,当时没有认清楚形式,所有有时候改变了a1,忘了a0……  导致各种错误,后来经过我不懈努力的输出中间过程,终于查明了原因!    后来又改又改……  终于AC了

但是现在反思,不该这样弄vis,应该把原数组改成0,这样就不用判断是否已经击毁,还要不要减去,回溯的时候用一个中间变量记录一下就可以了!
先贴自己的代码,再贴别人的代码!  一个小题让让我学到了不少!    不要动不动弄什么哨兵,直接在前面加一个判断,把越界的回归到1-n上来就好了,还不用引入什么别的变量,也就不会出现a1,a0要同步变化的你麻烦事了……

#include<iostream>#include<cstdio>#include<cstring>#include<stack>using namespace std;#define INF 0x7fffffffint n,sum;int num[29];int vis[29];int ans;stack <int> sta;void DFS(int dma,int tans){    if(tans>=ans)return ;///没有进行下去的必要了    if(dma==0)    {        ans=min(ans,tans);///更新最优解        return ;    }    for(int i=1; i<=n; ++i)    {        if(!vis[i])        {            int s1=i-1,s2=i+1;            if(s1==0)s1=n;            if(s2==n+1)s2=1;            if(vis[s1])s1=24;            if(vis[s2])s2=24;            dma-=num[i];  dma-=num[s1];  dma-=num[s2];            vis[i]=1; vis[s1]=1; vis[s2]=1;            tans+=dma;            DFS(dma,tans);            ///sta.pop();  下面是回溯,先把个状态回复到DFS前的状态            tans-=dma;            dma+=num[s1];  dma+=num[s2]; dma+=num[i];            vis[s1]=0;  vis[s2]=0;  vis[i]=0;        }    }}int main(){    while(scanf("%d",&n)!=EOF)    {        ans=INF;        sum=0;        num[0]=0;        memset(vis,0,sizeof(vis));        memset(num,0,sizeof(num));        for(int i=1; i<=n; ++i)        {            scanf("%d",&num[i]);            sum+=num[i];        }        DFS(sum,0);///总的怪兽数和当前受到的伤害数目        cout<<ans<<endl;    }    return 0;}

贴上别人的代码:
值得研究下:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm> using namespace std; const int N=50;const int INF=0x7fffffff;int a[N];int ans;int n;void dfs(int L,int an,int I){    for(int i=1;i<=n;++i)    {        int i1=(i-1>=1)?i-1:n,i2=(i+1<=n)?i+1:1;        int temp=a[i]+a[i1]+a[i2];        if(temp>0)        {             if(L-temp==0)            {                if(an<ans)                {ans=an;}                continue;            }            if(an+L-temp<ans)            {                int c=a[i],c1=a[i1],c2=a[i2];                a[i]=0;a[i1]=0;a[i2]=0;                dfs(L-temp,an+L-temp,I+1);                a[i]=c,a[i1]=c1,a[i2]=c2;            }        }    }}int main(){    //freopen("data.txt","r",stdin);    while(scanf("%d",&n)!=EOF)    {        int sum=0;        for(int i=1;i<=n;++i)        {            scanf("%d",&a[i]);            sum+=a[i];        }        ans=INF;        dfs(sum,0,0);        printf("%d\n",ans);    }    return 0;}
1152. False Mirrors    URAL  解题报告

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 被公司起诉我该怎么办 支付宝付款刷脸怎么办 考到了差的中学怎么办 中学考高中没考上怎么办 如果考中学没有考上那怎么办 摩托车牌京b牌照怎么办 老公网贷还不了怎么办 丈夫欠下的债妻子怎么办 丈夫偷妻子的钱怎么办 刷信用卡显示不允许降级交易怎么办 每次月经头几天下不来怎么办 邮箱和安全问题都忘记了怎么办 大疆air无人机芯片过热怎么办 脸上反复冒痘痘闭口粉刺怎么办? 手被火烧伤起泡怎么办 手被打火机烧了怎么办 小孩手被火烧了怎么办 手指被火烧伤了怎么办 别人砸坏我家门怎么办 逆水寒经验满了怎么办 tcl魔环显示离线怎么办 城管执法局执法不公平怎么办 人被骗去搞传销怎么办 进了传销想出来怎么办 武汉江夏健康证怎么办 健康证条子掉了怎么办 送外卖的健康证怎么办 美团没有健康证怎么办 健康证不给补办怎么办 南京怎么办健康证去哪里办 浙江横店健康证怎么办 办健康证查乙肝怎么办 餐饮健康证丢了怎么办 办健康证吃了东西怎么办 吃宵夜脸肿了怎么办 晚上不吃宵夜饿了怎么办 办健康证身份证丢了怎么办 宁波二院怎么办健康证 健康证和培训证怎么办 楼下烧煤炉呛人怎么办 衣服染了笔渍怎么办