hdu 1565 方格取数(1)

#include<iostream>
#include<stdio.h>
using namespace std;
int num[20000];
int dp[2][20000];
int a[20][20];
int n;
void dfs(int deep,int tot)
{
     for ( int i = deep ; i < n ; i ++ )
     {
         num[0]++;
         num[num[0]]=tot+(1<<i);   
         dfs(i+2,num[num[0]]);
     }
}
int ff(int i,int j)
{
   /*int k=0,total=0,g=j;
   while(g/2!=0||g%2==1)
   {
     g=g/2;
     k=k+1;
   }       
   while(j/2!=0||j%2==1)
   {
     k--;               
     if(j%2==1)
        total+=a[i][k]; 
     j=j/2;
   }
   */
   int  k=-1 , total = 0 ;
   while ( j>0)
   {
       k++;
       if ( j&1 )   total+=a[i][k];
       j=j/2;
   }
   return total;
}
int main()
{
    while(cin>>n)
    {
      num[0]=1;   num[1]=0;
      dfs(0,0); 
      for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
        {
           cin>>a[i][j];
        }
        if(n==1) { cout<<a[0][0]<<endl; continue;}
        for(int i=1;i<=num[0];i++)
        {
             dp[0][i]=0;
             dp[1][i]=0;
        } //cout<<ff(0,5)<<endl;
        for(int i=1;i<=num[0];i++)
          for(int j=1;j<=num[0];j++)
          {
            if(((num[i] & num[j])==0)  &&((ff(0,num[i])+ff(1,num[j]))>dp[1][j]))//{
              dp[1][j]=ff(0,num[i])+ff(1,num[j]);
            // cout<<num[i]<<" "<<num[j]<<" "<<dp[1][j]<<endl;}
          }
        int pre=0,now=1;
        for(int i=2;i<n;i++)
        {
          pre=(pre+1)%2;
          now=(now+1)%2;
          for(int j=1;j<=num[0];j++)
          {
           
            for(int k=1;k<=num[0];k++)
            {
                 if(j==1) dp[now][k]=0;   
              if(((num[j] & num[k])==0)&&(dp[pre][j]+ff (i,num[k])>dp[now][k]))
                dp[now][k]=dp[pre][j]+ff(i,num[k]);
                
            }
            
          }
        }
        int ans=0;
        for(int i=1;i<=num[0];i++)
        {
          if(dp[now][i]>ans)
           ans=dp[now][i];
        }
        cout<<ans<<endl;
    }
     
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值