繁体   English   中英

贪婪与动态规划

[英]greedy vs dynamic programming

Xaero 住在一个叫 Hackland 的国家。 Hackland 具有树状结构,其中 N 个城市由 N-1 条双向道路连接。 每个城市都有一个介于 [1,N] 之间的索引,并且没有两个城市具有相同的索引。

哈克兰总统认为在城市内旅行是安全的。 然而,由于哈克兰的照明条件差,在城市 A 和不同的城市 B 之间旅行并不安全。

为了确保从一个城市到另一个城市的人们的安全,哈克兰总统决定在该国安装一些灯。 每个城市最多可以安装 1 盏灯。 甚至有可能一些城市已经安装了灯。 根据总统的说法,从一个城市 A 到另一个城市 B 的旅行被认为是安全的,如果该路径上至少有 1 个城市安装了灯。

Xaero 知道 Hackland 的预算非常有限。 因此,他想通过告诉他要安装的最少数量的灯来帮助他的总统,以便从每个城市到每个其他城市的旅行变得安全。

输入格式

输入的第一行包含一个整数 T,表示测试用例的数量。 每个测试用例的第一行包含一个整数 N,表示该国名为 Hackland 的城市数量。 每个测试用例的下一行包含 N 个空格分隔的整数,表示国家的初始配置,即第 i 个位置的“0”表示第 i 个城市没有安装灯,而第 i 个位置的“1”表示已经安装了灯第 i 个城市。 每个测试用例的接下来 N-1 行包含一对整数 U 和 V,表示在城市 U 和城市 V 之间存在一条双向道路。

我的方法::

对于这个问题,我使用的方法是,我总是选择最大度数的节点。 减轻它(即使其 deg 为 0,并将其相邻节点的 deg 减少 1),我将继续执行此过程,直到任何节点的 deg 大于零。 对于已经变亮的节点,我将它们的 deg 设为 0 并将其相邻节点的 deg 减少 1。但是我的 ans 对于某些测试用例不正确?? 任何人都可以建议我的方法有什么问题吗?

我在这里分享代码......

#include<bits/stdc++.h>
using namespace std;

int main() {
    /* Enter your code here. Read input from STDIN. Print output to STDOUT */  

    int T, i, j, max, max_index, index, count, strt, end , N ;        
    bool flag ;

    cin>> T ;        
    while(T--)            
        {            
           cin >> N ;            
           count = 0 ;            
           vector<vector<int>> tree ;            
           vector<int> init(N+1) ;            
           vector<int> deg(N+1) ;            
           fill(deg.begin(),deg.end(),0) ;            
           tree.resize(N+1) ;            
           for(i=1; i<=N; i++)
               cin >> init[i] ;

           for(i=0 ; i < N-1 ; i++)                   
               {                   
               cin>>strt>>end ;                   
               tree[strt].push_back(end) ;                   
               tree[end].push_back(strt) ;                   
               deg[strt] = deg[strt] + 1 ;                   
               deg[end] = deg[end] + 1 ;
              }

           for(i=1; i <=N ; i++)                   
               {                   
                 if(init[i]==1)                         
                     {                         
                         deg[i] = 0 ;                         
                         for(j=0 ; j < tree[i].size(); j++)                                 
                             {                                 
                                index = tree[i][j] ;                                 
                                 deg[index] = deg[index] -1 ;                                 
                             }
                     }                   
             }                                    

       while(1){               
       flag = false ;  //               
       for(i=1 ; i<= N ; i++)               
           {                
              if(deg[i] > 0){
                  flag = true ;                     
                  break ;
              }
         }               
        if(flag==false)
            break ;

        max = deg[1] ;  //            
        max_index =  1;  //            
        for(i=2; i <= N ;i++)
            {                
             if(deg[i] > max)
                {                     
                 max = deg[i] ;                     
                 max_index = i ;
                }                
           }               
        //   cout<<"max_index "<<max_index <<endl ;               
           count = count + 1 ;   // 

          deg[max_index] = 0 ;

          for(j=0; j < tree[max_index].size() ; j++)                  
              {                  
                 index = tree[max_index][j] ;                  
                 deg[index] = deg[index]- 1 ; //                  
              }            
        }

      cout<<count<<endl ;  
    }

    return 0;
}

您的方法是贪婪的,而真正的解决方案是基于 DP(正如您的标题所暗示的那样)。 有很多可能出错的例子,但我认为这是一个 - 当多个节点具有相同的度数时你应该特别小心并明智地选择:

1
5
00000
1 2
1 3
2 4
3 5

请注意,即使您为此测试用例输出正确答案,也完全是靠运气——这里有 3 个 2 级节点,最好的解决方案是仅减轻其中的两个——2 和 3。取决于您的顺序给出相同的节点,你可能最终会点亮节点 1,这是错误的。 请注意 - 还有许多其他情况下您的解决方案是错误的,这只是我认为最简单的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM