SRM 554 DIV2

250pt

题意:

给定两个整数以及它们的个数,求由多少个整数由它们组成的,且两个数的个数差不超过1

 

分析:

暴力枚举。

 

View Code
class TheBrickTowerEasyDivTwo 
{ 
        public: 
        int find(int n, int a, int m, int b) 
        { 
            int i,j,k;
            bool dp[10000]={false};
            for(i=0;i<=n;i++)
                for(j=max(i-1,0);j<=i+1;j++)
                if(j<=m){
                        dp[i*a+j*b]=true;
                }
            for(i=1,k=0;i<10000;i++)
                if(dp[i])
                    k++;
            return k;
        } 
        

 
}; 

 

 

500pt:

题意:

n座高度为h[i]的塔,当塔倒下时为了不碰到相邻的塔,它们之间的距离取max(h[i],h[i-1],h[i+1]),重新排列塔的顺序,使第1座塔距第n座塔最短。

 

分析:

因为n<=7,直接DFS暴力枚举全排列。

 

View Code
class TheBrickTowerMediumDivTwo 
{ 
        public: 
        int vis[8];
        int n,ans;
        vector <int> c;
        void DFS(int i,int k,vector <int> a)
        {
            int j;
            vis[i]=k;
            if(k>=n-1)
            {
                int b[9],tmp=0;
                for(j=0;j<n;j++)
                    b[vis[j]]=j;
                for(j=1;j<n;j++)
                    tmp+=max(a[b[j]],a[b[j-1]]);
                if(tmp<ans)
                {
                    ans=tmp;
                    c.clear();
                    for(j=0;j<n;j++)
                        c.push_back(b[j]);
                }
                vis[i]=-1;
                return ;
            }
            for(j=0;j<n;j++)
                if(vis[j]==-1)
                    DFS(j,k+1,a);
            vis[i]=-1;
        }
        vector <int> find(vector <int> a) 
        { 
            n=a.size();
            memset(vis,-1,sizeof(vis));
            ans=1000000;
            for(int i=0;i<n;i++)
                DFS(i,0,a);
            return c;
        } 
        
 
}; 

 

 

1000pt:

题意:

给定四个有C种颜色的1*1*1的小方块组成2*2*1的大方块,由这种方块组成塔,给定塔的最高层数H,小方块的颜色数C,至多有K个相邻(有共同面)的小方块颜色相同,求塔的总数。

 

分析:

一看就是动态规划,只是担心状态数太多会超时,写起来又麻烦。

后来用状态压缩表示大方块就好写多了,dp[i][j][k]表示第i层大方块状态为j(0<=j<4^4)且有k种相邻颜色时有多少种。

O(4e7)都不超时,100ms

 

View Code
unsigned dp[48][256][9];

class TheBrickTowerHardDivTwo 
{ 
        public: 
        int find(int C, int K, int H) 
        { 
            int i,j,k,t,u,v,n=H,m=K,a[333][333],b[6],w[333],s=C*C*C*C;
            const int MOD=1234567891;
            for(k=0;k<s;k++)
            {
                w[k]=0;
                for(i=0,t=k;i<4;i++,t/=C)
                    b[i]=t%C;
                for(i=0;i<4;i++)
                    if(b[i]==b[(i+1)%4])
                        w[k]++;
            }
            for(i=0;i<s;i++)
                for(j=i;j<s;j++)
                {
                    a[i][j]=0;
                    int ti=i,tj=j;
                    for(k=0;k<4;k++,ti/=C,tj/=C)
                        if(ti%C==tj%C)
                            a[i][j]++;
                    a[j][i]=a[i][j];
                }
            memset(dp,0,sizeof(dp));
            for(j=0;j<s;j++)
                dp[0][j][w[j]]=1;

            for(i=0;i+1<n;i++)
                for(u=0;u<s;u++)
                    for(k=0;k<=m;k++)
                        if(dp[i][u][k])
                            for(v=0;v<s;v++)
                                if(k+w[v]+a[u][v]<=m)
                                    dp[i+1][v][k+w[v]+a[u][v]]=(dp[i+1][v][k+w[v]+a[u][v]]+dp[i][u][k])%MOD;
            unsigned ret=0;
            for(i=0;i<n;i++)
                for(j=0;j<s;j++)
                    for(k=0;k<=m;k++)
                        ret=(ret+dp[i][j][k])%MOD;
            return ret;
        } 
        

}; 


 

 

原文地址:https://www.cnblogs.com/xchaos/p/2720733.html