记一次在多哈的项目经历

题意:两个原子如果碰撞会释放出相应的能量,并且其中有一个原子碰撞后会湮灭。

求所有碰撞状态中释放出的能量的最大值。


分析:由于最多只有10个原子,所以可以用二进制枚举所有状态,二进制位上为1表示

该原子已经湮灭。0表示还没有。

dp方程: dp[i]表示i状态下得到的最大能量。

dp[i|tmp]=max(dp[i|tmp],dp[i]+mp[k][j]);  

dp[i]+mp[k][j]表示 第j个原子和第k个原子碰撞,第j个原子湮灭产生的能量。

tmp是由i上转移过来的,tmp=i|(1<<j)。


#include<cstdio>
#include<iostream>
#include<cstring>
#define maxn (1<<10)
using namespace std;

int dp[maxn],mp[15][15];

int maxx(int x,int y)
{
    return x>y?x:y;
}

int main()
{
    int n,tot,tmp,ans;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0) break;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                scanf("%d",&mp[i][j]);
            }
        }
        memset(dp,0,sizeof(dp));
        tot=(1<<10);
        for(int i=0;i<tot;i++)
        {
            for(int j=0;j<n;j++)
            {
                int tmp1=(1<<j);
                if((i&tmp1)==0)
                {
                    for(int k=0;k<n;k++)
                    {
                        int tmp2=(1<<k);
                        if((i&tmp2)==0 && j!=k)
                            dp[i|tmp1]=maxx(dp[i|tmp1],dp[i]+mp[k][j]);
                    }
                }
            }
        }
        ans=0;
        for(int i=0;i<tot;i++)
        {
            if(dp[i]>ans)
                ans=dp[i];
        }
        printf("%d\n",ans);
    }
    return 0;
}


也可以用个数组把所有状态存起来方便用。

即把10个位置每个原子湮灭的状态表示在数组state中。


#include<cstdio>
#include<iostream>
#include<cstring>
#define maxn (1<<10)+10
using namespace std;

int dp[maxn],mp[15][15];
int state[11]={1,2,4,8,16,32,64,128,256,512,1024};

int maxx(int x,int y)
{
    return x>y?x:y;
}

int main()
{
    int n,tot,ans;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0) break;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                scanf("%d",&mp[i][j]);
            }
        }
        memset(dp,0,sizeof(dp));
        for(int i=0;i<state[n];i++)
        {
            for(int j=0;j<n;j++)   //枚举每一个原子
            {
                if((i&state[j])==0)   //如果这个原子还没被湮灭
                {
                    for(int k=0;k<n;k++)   //则找另一个还没湮灭的原子于j原子碰撞
                    {                         //使j原子湮灭
                        if((i&state[k])==0 && j!=k)
                            dp[i|state[j]]=maxx(dp[i|state[j]],dp[i]+mp[k][j]);
                    }
                }
            }
        }
        ans=0;
        for(int i=0;i<state[n];i++)
        {
            if(dp[i]>ans)
                ans=dp[i];
        }
        printf("%d\n",ans);
    }
    return 0;
}


记一次在多哈的项目经历

上一篇:初尝试Android Studio


下一篇:理解 I/O-- 阻塞、非阻塞,同步、异步的概念及其区别