zoukankan      html  css  js  c++  java
  • NYOJ 1249 物资调度(DFS+剪枝)

    题目链接:

    http://acm.nyist.net/JudgeOnline/problem.php?pid=1249

    描述

    某地区发生了地震,灾区已经非常困难,灾民急需一些帐篷、衣物、食品和血浆等物资。可通往灾区的道路到处都是塌方,70%以上的路面损坏,桥梁全部被毁。国家立即启动应急预案,展开史上最大强度非作战空运行动,准备向灾区空投急需物资。

    一方有难,八方支援。现在已知有N个地方分别有A1,A2,….,An个物资可供调配。目前灾区需要物资数量为M。

    现在,请你帮忙算一算,总共有多少种物质调度方案。

    假设某地方一旦被选择调配,则其物资数全部运走。

     
    输入
    输入一个组数T。(0<T<10)
    之后为N,M含义分别如题目描述。(0<N<=100,0<M<=1000)
    之后有N个数字A1,A2,….,An表示N个地方每个地方的物资数。(0<Ai<=1000)
    输出
    对于每组测试数据,输出一行:物资调度的总方案数
    样例输入
    2
    4 4
    1 1 2 2
    4 6
    1 1 2 2
    样例输出
    3
    1
    来源 第七届河南省程序设计大赛
    题意描述:
    输入物资的堆数及所需调动的物资数、每堆物资数
    计算并输出调度方案数
    解题思路:
    可以看成是有相同牌面的不同纸牌的排列,使用DFS的话,必定需要剪枝,因为全排列10张以上的牌速度就慢的可怕了(别说100张了),所以在搜索的时候向下传递i值,意即下次尝试的时候直接从后面取就行了,这样就避免了重复取牌。另外取的时候直接判断会不会超出限度,是的话直接剪掉。详见代码。
    AC代码:
     1 #include<stdio.h>
     2 #include<string.h>
     3 void dfs(int step,int sum,int i);
     4 int ans,n,v,book[110],a[110];
     5 int main()
     6 {
     7     int T,i,z;
     8     scanf("%d",&T);
     9     while(T--)
    10     {
    11         scanf("%d%d",&n,&v);
    12         z=0;//物资总和 
    13         for(i=1;i<=n;i++)
    14         {
    15             scanf("%d",&a[i]);
    16             z += a[i];
    17         }
    18         if(z <= v)
    19         {
    20             if(z<v)
    21             printf("0
    ");
    22             else
    23             printf("1
    ");
    24             continue;
    25         }    
    26         
    27         ans=0;
    28         memset(book,0,sizeof(book));
    29         dfs(1,v,1);//向下传递放牌位置,所需物资数,取牌位置 
    30         printf("%d
    ",ans);
    31     }
    32     return 0;
    33 }
    34 void dfs(int step,int sum,int i)
    35 {
    36     int j;
    37     if(step==n+1 || sum ==0) 
    38     {
    39         if(sum == 0)
    40             ans++;
    41         return;
    42     }
    43     for(;i<=n;i++)
    44     {
    45         if(sum < a[i])//必要剪枝 
    46         continue;
    47         if(!book[i])
    48         {
    49             book[i]=1;
    50             sum -= a[i];
    51             dfs(step+1,sum,i+1);
    52             
    53             book[i]=0;
    54             sum += a[i];
    55         }
    56     }
    57     return ;
    58 }
  • 相关阅读:
    python学习(二十三) String(下) 分片和索引
    python学习(二十二) String(上)
    微服务网关
    【转】linux 软连接 硬链接
    设计模式--观察者模式
    设计模式--策略模式
    ubuntu-server 安装redis
    【转】linux的hostname修改详解
    【转】ftp的两种模式
    【转】linux下find查找命令用法
  • 原文地址:https://www.cnblogs.com/wenzhixin/p/7412323.html
Copyright © 2011-2022 走看看