Codeforces Round #369 (Div. 2)

题目链接:

A. Bus to Udayland

B. Chris and Magic Square

C. Coloring Trees

分析:

(做出几道说几道QAQ)

A:简单模拟,把相邻OO改成++即可;

B:

找magic number,找到满足每行和==每列和==两对角线和即可,只需先用两行和之差确定magic number,代入进去,然后依次判断即可;

C:

dp题,dp[i][j][k]表示前i棵树的beauty为j时第i棵树的color为k-th color
状态转移:如果第i棵树已涂色,比较i-1时颜色相同与不同情况下的油漆用量大小,如果没涂,则涂色(1~m),同上比较,详情见代码

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <bitset>
using namespace std;

typedef long long LL;
#define F(i,a,b) for(int i=a;i<=b;++i)
#define Rof(i,a,b) for (int i=(a),_##i=(b); i>=_##i; i--)
#define rep(i,a,b) for (int i=(a),_##i=(b); i<=_##i; i++)
#define rek(i,a,b) for (int i=(a),_##i=(b); i>=_##i; i--)
#define mem(a,b) memset(a,b,sizeof(a))
#define Cpy(a,b) memcpy(a,b,sizeof(b))
const LL inf = LL(1e18);;
int n,m,k;
LL tree[101],cost[101][101],dp[101][101][101],coun;
//dp[i][j][k]表示前i棵树的beauty为j时第i棵树的color为k-th color
//状态转移:如果第i棵树已涂色,比较i-1时颜色相同与不同情况下的油漆用量大小
//如果没涂,则涂色(1~m),同上比较,详情见代码 
int main()
{
    //freopen("in.txt","r",stdin);
    scanf("%d %d %d",&n,&m,&k);
    for(int i=1;i<=n;++i) scanf("%I64d",tree+i);
    for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) 
    {
        scanf("%I64d",&cost[i][j]);
    }
    //memset只用于赋值0,其它不要乱用 
    F(i,0,n)F(j,0,k)F(p,0,m) dp[i][j][p]=inf;
    //对第一棵树涂色判断 
    if(tree[1]) dp[1][1][tree[1]]=0;
    else
    {
        F(i,1,m) dp[1][1][i]=cost[1][i];
    }
    F(i,2,n)
    {
        for(int j=1;j<=i&&j<=k;j++)
        {
            if(!tree[i])
            {
                F(k,1,m) 
                {
                    dp[i][j][k]=min(dp[i][j][k],dp[i-1][j][k]+cost[i][k]);//第i-1棵树颜色与第i棵树相同 
                    F(p,1,m) if(p!=k) dp[i][j][k]=min(dp[i][j][k],dp[i-1][j-1][p]+cost[i][k]);//第i-1棵树与第i棵树颜色不同 
                }
            }
            else
            {
                dp[i][j][tree[i]]=min(dp[i-1][j][tree[i]],dp[i][j][tree[i]]);//第i-1棵树颜色与第i棵树相同 
                F(p,1,m) if(p!=tree[i]) dp[i][j][tree[i]]=min(dp[i][j][tree[i]],dp[i-1][j-1][p]);//第i-1棵树与第i棵树颜色不同
            }
        }
    }
    LL coun=inf;
    F(i,1,m) coun=min(coun,dp[n][k][i]);//比较前n棵树beauty为k时的油漆用量大小,仍为inf则输出-1 
    if(coun>=inf) puts("-1");
    else printf("%I64d\n",coun);
     return 0;
}
View Code

 

posted @ 2016-08-30 08:55  遗风忘语  阅读(161)  评论(0编辑  收藏  举报