Codeforces Round #369 (Div. 2)
题目链接:
分析:
(做出几道说几道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; }
一直地一直地往前走