• hdu1565


                                   方格取数(1)

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 3600    Accepted Submission(s): 1373


    Problem Description
    给你一个n*n的格子的棋盘,每个格子里面有一个非负数。
    从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
     
    Input
    包括多个测试实例,每个测试实例包括一个整数n 和n*n个非负数(n<=20)
     
    Output
    对于每个测试实例,输出可能取得的最大的和
     
    Sample Input
    3
    75 15 21
    75 15 28
    34 70 5
     
    Sample Output
    188
    #include<iostream>
    #include<cstring>
    #include<string>
    #include<cstdio>
    using namespace std;
    int save[1<<20+1],map[40][40];
    int dp[3][1<<20+1],cnt,n;
    int max1(int a,int b)
    {
        return a > b ? a : b;
    }
    bool ok(int x)
    {
        if( x& (x>>1)) return false;
        //    if(x & (x<<2)) return false;
        return true;
    }
    
    int getsum(int f,int k)
    {
              int ans=0;
              for(int i=0;i<n;i++)
              {
                  if(k & (1<<i))
                      ans+=map[f][i];
              }
              return ans;
    }  
    
    bool match(int l,int r)
    {
        if(l & r) return false;
        return true;
    }
    
    int slove()
    {
        int i,j,k;
        for(i=0;i<cnt;i++)
        {
            dp[0][i] = getsum(0,save[i]);
        }
        for(i=1;i<=n;i++)    
        {
            for(j=0;j<cnt;j++)
            {
                dp[i%2][j] = 0;
                for(k=0;k<cnt;k++)
                {
                    if(match(save[j],save[k]))
                    {
                        dp[i%2][j]=max1(dp[i%2][j],dp[(i+1)%2][k]+getsum(i,save[j]));
                    }
                }
            }
        }    
                    
        int ans=0;
        for( i=0;i<cnt;i++)
            ans=max1(ans,dp[(n+1)%2][i]);
        printf("%d
    ",ans);
        return ans;
    }
    
    int main()
    {
        //int n;
        while(~scanf("%d",&n))
        {
            int i,j;
            memset(dp,0,sizeof(dp));
            for(i=0;i<n;i++)
            {
                for(j=0;j<n;j++)
                {
                    scanf("%d",&map[i][j]);
                }
            }
            cnt = 0;
            for(i=0;i<(1<<n);i++)
            {
                if(ok(i))
                {
                    save[cnt++] = i;
                    //save[cnt++]  = getsum(i);
                }
            }
            slove();
        }
        return 0;
    }
  • 相关阅读:
    Java面向对象基本/传参/引用/访问控制/构造器
    二叉树遍历&分治
    Java基础 & 基本数据类型 & String类
    Java面向对象继承/重写/多态
    Java集合基础
    Java面向对象抽象类/接口类/内部类
    你碰我变
    cookie&&localstorage
    父亲的谎话,只有长大后才能听懂……
    CSS的兼容性
  • 原文地址:https://www.cnblogs.com/Deng1185246160/p/3266142.html
Copyright © 2020-2023  润新知