Fighting for Triangles

题目连接:

http://codeforces.com/gym/100015/attachments

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 fives 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 first. Note that if a triangle exists on the board

before the first 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

Hint

题意

给你一个四层的三角形,一共有18条边

然后A,B两个开始划线,如果当前人划线的时候,正好化成了一个小三角形,他就加一分,并且可以再画

否则就该另外一个人画

然后告诉你一些边已经被画过线了,问你先手是否能够胜利

题解:

直接暴力状压dp就好了

dp[i]表示i这个状态的时候,A能够拿到的最多数

注意trick,就是画线的时候,不仅仅可以占据一个三角形,有可能占据两个三角形哦

代码

#include<bits/stdc++.h>
using namespace std; int dp[1<<21][2];
int Dis[1<<21][2];
int cal(int x)
{
int vis[30];
memset(vis,0,sizeof(vis));
for(int i=1;i<=18;i++)
if((x>>i)&1)
vis[i]=1;
int ans = 0;
for(int i=0;i<6;i++)
if(vis[i*3+1]&&vis[i*3+2]&&vis[i*3+3])
ans++;
if(vis[3]&&vis[5]&&vis[7])ans++;
if(vis[6]&&vis[11]&&vis[13])ans++;
if(vis[9]&&vis[14]&&vis[16])ans++;
return 9-ans;
}
int dfs(int now,int flag)
{
if(Dis[now][flag])return dp[now][flag];
int last = cal(now);
Dis[now][flag]=1;
for(int i=1;i<=18;i++)
{
if(((now>>i)&1)==0)
{
int next = now|(1<<i);
int flag3 = cal(now)-cal(next);
if(flag3>0)
dp[now][flag]=max(dp[now][flag],dfs(next,flag)+flag3);
else
dp[now][flag]=max(dp[now][flag],last-dfs(next,1-flag));
}
}
return dp[now][flag];
} int main()
{
//freopen("1.in","r",stdin);
int n;
while(cin>>n)
{
if(n==0)break;
int now = 0;
for(int i=0;i<n;i++)
{
int x;scanf("%d",&x);
now|=(1<<x);
}
int last = cal(now);
int a = dfs(now,0);
int b = last - a;
//cout<<last<<" "<<a<<" "<<b<<endl;
if(a>b)
cout<<"Andy wins"<<endl;
else if(a==b)
cout<<"Draw"<<endl;
else if(a<b)
cout<<"Ralph wins"<<endl;
}
}

Codeforces Gym 100015F Fighting for Triangles 状压DP的更多相关文章

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

    F Fighting for Triangles Description Andy and Ralph are playing a two-player game on a triangular bo ...

  2. codeforces gym #101161H - Witcher Potion(状压DP)

    题目链接: http://codeforces.com/gym/101161/attachments 题意: 总共有n瓶药可供选择 每瓶药可以增加$e_i$点体力,和$p_i$点毒性 每分钟消耗1点毒 ...

  3. codeforces 342D Xenia and Dominoes(状压dp+容斥)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud D. Xenia and Dominoes Xenia likes puzzles ...

  4. Codeforces 375C - Circling Round Treasures(状压 dp+最短路转移)

    题面传送门 注意到这题中宝藏 \(+\) 炸弹个数最多只有 \(8\) 个,故考虑状压,设 \(dp[x][y][S]\) 表示当前坐标为 \((x,y)\),有且仅有 \(S\) 当中的物品被包围在 ...

  5. Codeforces Beta Round #16 E. Fish (状压dp)(概率dp)

    Codeforces Beta Round #16 (Div. 2 Only) E. Fish 题目链接:## 点击打开链接 题意: 有 \(n\) 条鱼,每两条鱼相遇都会有其中一只吃掉对方,现在给你 ...

  6. Codeforces 580D Kefa and Dishes(状压DP)

    题目大概说要吃掉n个食物里m个,吃掉各个食物都会得到一定的满意度,有些食物如果在某些食物之后吃还会增加满意度,问怎么吃满意度最高. dp[S][i]表示已经吃掉的食物集合是S且刚吃的是第i个食物的最大 ...

  7. CodeForces 385 D.Bear and Floodlight 状压DP

    枚举灯的所有可能状态(亮或者不亮)(1<<20)最多可能的情况有1048576种 dp[i]表示 i 状态时灯所能照射到的最远距离(i 的二进制中如果第j位为0,则表示第j个灯不亮,否则就 ...

  8. Codeforces 599E Sandy and Nuts(状压DP)

    题目链接 Sandy and Nuts 题意大概就是给出限制条件求出在该限制条件下树的种数. #include <bits/stdc++.h> using namespace std; # ...

  9. Codeforces Gym 100610 Problem K. Kitchen Robot 状压DP

    Problem K. Kitchen Robot Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/10061 ...

随机推荐

  1. selenium python (十)浏览器多窗口处理

    #!/usr/bin/python# -*- coding: utf-8 -*-__author__ = 'zuoanvip'#在测试过程中有时候会遇到出现多个浏览器窗口的情况,这时候我们可以通过窗口 ...

  2. UI控件入门

    其实整个学习过程.确实有点儿混乱,因为不懂的东西太多,一会儿看这,一会儿看那,马上就乱了. 还是先做点儿简单的事儿,说控件,但不会说完全,只是入个门,知道怎么学控件,具体要学好每一个控件需要项目中磨练 ...

  3. 常用SQL整理

    整理了日常用到的一些sqls 1.插入表 insert into table_B select * from table_A 2.清空表 truncate table test #清空表,结构还存在d ...

  4. kali ssh 登录

    kali 开启ssh 登录:可在windows 中通过 xshell 登录,方便操作. 修改sshd_config文件, vi /etc/ssh/sshd_config 将#PasswordAuthe ...

  5. c# 范型Dictionary实用例子

    //定义 public static Dictionary<string, object> dict =new Dictionary<string, object>(); // ...

  6. 监听mysql是否挂了

    监听mysql是否挂了,如果挂了就重启mysql 方式一: #!/bin/bash pgrep -x mysqld &> /dev/null if [ $? -ne 0 ] then e ...

  7. SharePoint咨询师之路:备份和恢复系列三 - 备份web和服务应用程序

    本系列包括: 备份服务器场和配置 备份web和服务应用程序 备份内容数据库 备份网站集 备份自定义项 备份web应用程序和服务应用程序一样有三种方式:SharePoint管理中心网站.Windows  ...

  8. 细说OpenSessionInView问题

    [环境参数] 环境:SSH框架 [问题描述]  NoSession问题 HibernateTemplate对象提供的方法如果使用“延迟加载”,Session对象的管理不受开发者控制,此时如果在表现层获 ...

  9. HTML5每日一练之figure新标签的应用

    igure元素是一种元素的组合,可带有标题(可选).figure标签用来表示网页上一块独立的内容,将其从网页上移除后不会对网页上的其他内容产生影响.figure所表示的内容可以是图片.统计图或代码示例 ...

  10. hdu 1199 Color the Ball

    http://acm.hdu.edu.cn/showproblem.php?pid=1199 Color the Ball Time Limit: 2000/1000 MS (Java/Others) ...