Codeforces Gym 100015F Fighting for Triangles 状态压缩DP

       F Fighting for Triangles     

Description

Andy and Ralph are playing a two-player game on a triangular board that looks like the following:

1 2
3
4 5 7 8
6 9
10 11 13 14 16 17
12 15 18

At each turn, a player must choose two adjacent vertices and draw a line segment that connects them.
If the newly drawn edge results in a triangle on the board (only the smallest ones count), then the player
claims the triangle and draws another edge. Otherwise, the turn ends and the other player plays. The
objective of the game is to claim as many triangles as possible. For example, assume that it is Andy’s turn,
where the board has ?ves edges as shown in the picture below. If Andy draws edge 6, then he will claim the
triangle formed by edge 4, 5, and 6, and continue playing.

Given a board that already has some edges drawn on it, decide the winner of the game assuming that
both Andy and Ralph play optimally. Andy always goes ?rst. Note that if a triangle exists on the board
before the ?rst move, neither player claims it.

Input

The input consists of multiple test cases. Each test case begins with a line containing an integer N,5 !
N ! 10, which indicates the number of edges that are already present on the board before the game begins.
The next line contains N integers, indicating the indices of these edges. The input terminates with a line
with N = 0. For example:

Output

For each test case, print out a single line that contains the result of the game. If Andy wins, then print out
“Andy wins”. If Ralph wins, then print out “Ralph wins”. If both players get the same number of triangles,
then print out “Draw”. Quotation marks are used for clarity and should not be printed. For example, the
correct output for the sample input above would be:

Sample Input

6

1 2 3 4 5 6

5

4 5 6 7 8

0

Sample Output

Andy wins

Ralph wins

题意:给一个图, 是一个正三角形,在三角形内部(包括边缘)有18个点,每次你可以去相邻的点画一条线段,假如这条线段可以和相邻的点构成一个新的三角形,那么价值+1

    现在有两个人玩这个比赛,A先手,假如A不能获取价值 才轮到B 知道所有可能的线段全部画完,问你A,B谁获取的价值更大

  开始给你n个点,表示这n个点间有线段已经被画完

题解:电数n<=18我们设定 x为当前被画掉的状态,且f先手

那么 记忆花搜索dp[x][f] 表示就是当前x情况下 f先手  a 取得的价值是多少

  爆搜记忆就好

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std ;
typedef long long ll;
const int N = 1<<21;
int dp[N][2],v[21];
int cal(int x) {
    memset(v,0,sizeof(v));
    int ret = 0;
    for(int i = 17; i >= 0; i--) if(x & (1<<i)) v[i + 1] = 1;
    for(int i = 1; i <= 16; i += 3) {
        if(v[i] && v[i+1] && v[i+2]) ret++;
    }
    if(v[3] && v[5] && v[7]) ret++;
    if(v[6] && v[11] && v[13]) ret++;
    if(v[9] && v[14] && v[16]) ret++;
    return ret;
}
int dfs(int n,int f) {
    if(dp[n][f] != -1) return dp[n][f];
    int last = 9 - cal(n);
    dp[n][f] = 0;
    for(int i = 0; i < 18; i++) {
        if(((1<<i) & n) != 0) continue;
        int nex = n|(1<<i);
        int g = cal(nex) - cal(n);
        if(g) dp[n][f] = max(dp[n][f],dfs(nex,f) + g);
        else dp[n][f] = max(dp[n][f], last - dfs(nex,1-f));//
    }
    return dp[n][f];
}
int main() {
    int n, x;
    memset(dp,-1,sizeof(dp));
    while(scanf("%d",&n)!=EOF) {
        if(n == 0) break;
        int f = 0;
        for(int i = 1; i <= n; i++) scanf("%d",&x), f |= (1<<(x-1));
        int last = 9 - cal(f);
       // for(int i = 1; i <= 18; i++)if(v[i]) printf("1");else cout<<0;
        int a = dfs(f,0);
        int b = last - a;
        if(a > b) printf("Andy wins\n");
        else if(a == b) printf("Draw\n");
        else printf("Ralph wins\n");
    }
    return 0;
}

代码

时间: 2024-08-10 06:05:57

Codeforces Gym 100015F Fighting for Triangles 状态压缩DP的相关文章

Codeforces 903F Clear The Matrix(状态压缩DP)

题目链接 Clear The Matrix 题意 给定一个$4 * n$的矩形,里面的元素为'.'或'*'.现在有4种正方形可以覆盖掉'*',正方形的边长分别为$1,2,3,4$. 求把整个矩形变成全'.'的最小代价. 考虑状压DP 设$f[i][j]$为前$i$列已经全部变成'.',第$i + 1$到第$i + 4$列的这$16$个格子状态为$j$的最小花费. 这$16$个格子标号如下 0   4   8   12 1   5   9   13 2   6  10  14 3   7  11 

hdoj 5125 Little Zu Chongzhi&#39;s Triangles【状态压缩dp】

题目:hdoj 5125 Little Zu Chongzhi's Triangles 题意:给出n个木棍的长度,然后问这些木棍所能组成三角形的最大面积. 分析:这个题目用状态压缩解,因为木棍的最大个数为12 我们枚举所有状态,用状态对应位的 0 和 1 表示这个木棍是否选择,然后如果某个状态选择的木棍是3的话,判断是否可以组成,可以的话dp[st] = 三角形面积 然后大于三的,分解之后得出转移方程dp[st] = max(dp[st],dp[i] + dp[st - i]) (i | (st

HDU 5135 Little Zu Chongzhi&#39;s Triangles(状态压缩dp+Vector)

这道题是水题,当时直接贪心就过了. 多阶段决策,其实应该用dp,他人的代码使用Vector进行预处理. #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<vector> using namespace std; int n, a[12]; double dp[1<<12]; double cal(int a, int b, i

hdu5135 Little Zu Chongzhi&#39;s Triangles(状态压缩dp)

题目链接:点击打开链接 题意描述:给定n(3=<n<=12)节木棍,从中选取一些组成多个三角形,每个三角形由3节木棍组成.问组成的三角形面积之和最大为多少? 解题思路: 刚开始暴力搜索发现当n=12时最多可以组成4个三角形,如果暴力搜索O(4^12==2^24)果断tle 所以考虑动态规划,由于n最大为12所以我们可以用二进制 表示是否要某节木棍.先预处理出每种可能的三角形,然后动态规划即可 代码: #include <cstdio> #include <cmath>

codeforces 425B Sereja and Table(状态压缩,也可以数组模拟)

题目 给出一个n*m的01矩阵, 让你最多改变k个里面的值(0变1,1变0), 使得0.1的连通分量是矩阵.输出最少步数 1 ≤ n, m ≤ 100; 1 ≤ k ≤ 10 题解: 如果01连通分量是矩形, 那么矩形一定是这样的: 0101010 1010101 0101010 1010101 (上面的01代表子矩阵块). 也就是每一行要么是相同,要么是相反的. 如果n>k, 肯定有一行是不能改变的,那么枚举这一行,然后其余的要么变相同,要么变相反,看最少的步数. 如果n<k ,那么可以枚举

Gym - 101915D Largest Group 最大独立集 Or 状态压缩DP

题面题意:给你N个男生,N个女生,男生与男生之间都是朋友,女生之间也是,再给你m个关系,告诉你哪些男女是朋友,最后问你最多选几个人出来,大家互相是朋友. N最多为20 题解:很显然就像二分图了,男生一边女生一边的,然后一种解法就是 求图的最大独立集,(看起来很巧,实则也是一种套路) (最大独立集是一个点集,其中任意两点在图中无对应边,对于一般图来说,最大独立集是一个NP完全问题,对于二分图来说最大独立集=|V|-二分图的最大匹配数) 我们本来连边是,所有的朋友关系连边(男女就行了,同性都可以忽略

UVa11795 Mega Man&#39;s Mission(状态压缩DP)

Mega Man's Mission Mega Man is off to save theworld again. His objective is to kill the Robots created by Dr.Wily whose motive is to conquer the world. In each mission, he willtry to destroy a particular Robot. Initially, Mega Man is equippedwith a w

POJ2288Islands and Bridges(状态压缩DP,求最大路和走条数)

Islands and Bridges Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 8845   Accepted: 2296 Description Given a map of islands and bridges that connect these islands, a Hamilton path, as we all know, is a path along the bridges such that i

POJ 3254 Corn Fields 状态压缩DP (C++/Java)

http://poj.org/problem?id=3254 题目大意: 一个农民有n行m列的地方,每个格子用1代表可以种草地,而0不可以.放牛只能在有草地的,但是相邻的草地不能同时放牛, 问总共有多少种方法. 思路: 状态压缩的DP. 可以用二进制数字来表示放牧情况并判断该状态是否满足条件. 这题的限制条件有两个: 1.草地限制. 2.相邻限制. 对于草地限制,因为输入的时候1是可以种草地的. 以"11110"草地分析,就只有最后一个是不可以种草的.取反后得00001  .(为啥取反