zoj 3471 Most Powerful

本文详细解析了ZOJ3471 Most Powerful问题的状态动态规划解法,利用二进制位表示粒子的存在状态,通过转移方程求解在不同状态下可释放的最大能量。最终找出仅剩一个粒子时的最大能量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:zoj 3471 Most Powerful  作者:jostree 转载请说明出处

很经典的状态dp,使用i的二进制位表示粒子的状态,0表示存在,1表示不存在。dp[i]表示在状态i的情况下能够释放的最大的能量,注意自身不能够发生碰撞。例如4个粒子的状态1100表示第0个和第1个粒子不存在,第2、3个粒子存在则可以转移到状态1110或1101。最终遍历只剩下一颗粒子的情况下的所有能量中的最大值。

代码如下:

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <iostream>
 4 #include <cstring>
 5 #define     MAXN 11
 6 using namespace std;
 7 int arr[MAXN][MAXN];
 8 int dp[1<<MAXN];
 9 int n;
10 void solve()
11 {
12     memset(dp, 0, sizeof(dp));
13     for( int i = 0 ; i < 1<<n ; i++ )
14     {
15         for( int j  = 0 ; j < n ; j++ )
16         {
17             if( ((1<<j) & i) == 0 )
18             {
19                 for( int k = 0 ; k < n ; k++ )
20                 {
21                     if( ((1<<k) & i) == 0 && k!= j )
22                     {
23                         dp[i|(1<<j)]  = max(dp[i|(1<<j)], dp[i] + arr[k][j]);
24                     }
25                 }
26             }
27         }
28     }
29     int ans = 0;
30     for( int i = 0 ; i < n ; i++ )
31     {
32         ans = max(ans, dp[((1<<n)-1)^(1<<i)]);
33     }
34     printf ( "%d\n", ans );
35 }
36 int main(int argc, char *argv[])
37 {
38     while( scanf ( "%d", &n ) && n )
39     {
40         for( int i = 0 ; i < n ; i++ )
41         {
42             for( int j = 0 ; j < n ; j++ )
43             {
44                 scanf ( "%d", &arr[i][j] );
45             }
46         }
47         solve();
48     }
49 }

 

转载于:https://www.cnblogs.com/jostree/p/4008592.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值