[SHOI2012] 火柴游戏
[SHOI2012] 火柴游戏
[题目链接]
[思路要点]
首先发现移动火柴操作可以放到最后做。每一次移动火柴一定可以看做是添加一根火柴再删除一根火柴,并且可以将任意一次添加和一次删除操作合并为一次移动操作,那么可以考虑只使用添加和删除操作,最后再计算出当前情况下使用几次移动操作最优。
然而发现并不清楚优先选择添加还是删除,但是我们知道当添加操作次数相同时,删除操作越少越优,所以可以 \(\text{dp}\),用状态 \(f[i][j]\) 表示当前考虑了前 \(i\) 个数字,当前的添加操作数量为 \(j\) 时的最少删除操作次数。
得到这个之后,对于每一对添加操作数量和删除操作数量,可以三分出移动操作数量或者直接枚举取最优解。
[代码]
#include<stdio.h>
#include<cmath>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn=205;
const int inf=0x7f7f7f7f7f;
int dp[maxn][505],p[5],q[5],n,ad[10][10],de[10][10];
int num[10][8]={{0,1,1,1,0,1,1,1},{0,0,0,1,0,0,1,0},{0,1,0,1,1,1,0,1},{0,1,0,1,1,0,1,1},{0,0,1,1,1,0,1,0},{0,1,1,0,1,0,1,1},{0,1,1,0,1,1,1,1},{0,1,0,1,0,0,1,0},{0,1,1,1,1,1,1,1},{0,1,1,1,1,0,1,1}};
char a[maxn],b[maxn];
int as(int s,int f)
{
int i,ans=0;
for(i=1;i<=7;i++)
if(num[s][i]==num[f][i])continue;
else if(num[s][i]==0) ans++;
return ans;
}
int ds(int s,int f)
{
int i,ans=0;
for(i=1;i<=7;i++)
if(num[s][i]==num[f][i])continue;
else if(num[s][i]==1) ans++;
return ans;
}
int getans(int i,int j)
{
int ans=inf,k,l=0,maxk=min(i,j);
for(k=0;k<=maxk;k++)
{
ans=min(ans,p[1]*(1+i-k)*(i-k)/2+(i-k)*q[1]+
p[2]*(1+j-k)*(j-k)/2+(j-k)*q[2]+
p[3]*(1+k)*k/2+k*q[3]);
}
return ans;
}
int main()
{
int i,j,k,m,ans=inf;
scanf("%d",&n);
scanf("%s %s",a,b);
scanf("%d%d%d%d%d%d",&p[1],&q[1],&p[2],&q[2],&p[3],&q[3]);
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
ad[i][j]=as(i,j);
de[i][j]=ds(i,j);
}
}
for(i=0;i<n;i++)
{
a[i]-='0',b[i]-='0';
}
for(i=1;i<=n;i++)
for(j=0;j<505;j++)
dp[i][j]=inf;
for(m=1;m<=n;m++)
for(k=0;k<10;k++)
{
int add=ad[a[m-1]][k]+ad[b[m-1]][k];
int del=de[a[m-1]][k]+de[b[m-1]][k];
for(i=0;i<505;i++)
if(i>=add)
dp[m][i]=min(dp[m][i],dp[m-1][i-add]+del);
}
for(i=0;i<505;i++)
if(dp[n][i]!=inf)
ans=min(ans,getans(i,dp[n][i]));
printf("%d",ans);
return 0;
}
[SHOI2012] 火柴游戏的更多相关文章
- 智力火柴游戏Android源码项目
该游戏源码是一个智力火柴游戏源码,游戏分为难.中.易三种模式,通过对火柴的移动来实现等式分成立,具有极好的市场价值和参考意义. 源码下载: http://code.662p.com/view/9741 ...
- Java实现去火柴游戏
package com.gh.p10; /** * Created by Lenovo on 2014/12/10. */ import java.util.Random; import java.u ...
- 取火柴游戏||Nim博弈
好久之前看的sg函数了 好像就记住一个nim博弈qwq 第一次啊看的时候很迷,现在感觉可以了qwq 首先我们来看一个其他的游戏.(以下游戏只有两个人参与,且足够聪明) 两个人在一张圆形的桌子上放等大的 ...
- java实现第三届蓝桥杯火柴游戏
火柴游戏 [编程题](满分34分) 这是一个纵横火柴棒游戏.如图[1.jpg],在3x4的格子中,游戏的双方轮流放置火柴棒.其规则是: 不能放置在已经放置火柴棒的地方(即只能在空格中放置). 火柴棒的 ...
- P1247 取火柴游戏
题目描述 输入k及k个整数n1,n2,-,nk,表示有k堆火柴棒,第i堆火柴棒的根数为ni:接着便是你和计算机取火柴棒的对弈游戏.取的规则如下:每次可以从一堆中取走若干根火柴,也可以一堆全部取走,但不 ...
- Luogu P1247 取火柴游戏
题目链接 \(Click\) \(Here\) 这个题目其实就是一个\(Nim\)游戏的简单模型.对于单个的\(Nim\)游戏(单独一堆的情况),数学归纳可证其\(SG\)函数值等于其石子个数.所以对 ...
- BZOJ2828 : 火柴游戏
设$f[i][j][k]$表示考虑了前$i$个数字,增加了$j$根火柴,删掉了$k$根火柴是否可能,用bitset加速DP. 然后设$g[i][j]$表示增加了$i$根火柴,删掉了$j$根火柴的最小代 ...
- 洛谷P1247 取火柴游戏
经典NIM游戏. 取XOR和即可. 注意输出方案时,找到大于异或和sum的,变为a[i] ^ sum即可. #include <cstdio> ; int a[N]; int main() ...
- 【洛谷】P1247 取火柴游戏(Nim)
题目 传送门:QWQ 分析 蒟蒻根本不会博弈论..... 只知道异或和判断Nim游戏.. 不是很懂输出的选择,所以发一篇博客以待复习 代码 #include <bits/stdc++.h> ...
随机推荐
- k3 cloud中获取自己开发的单据
设置基础资料(业务对象).系统自带用单据
- JavaScript基础3——使用Button提交表单
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- AOS Clustering on one Server
原文链接:http://www.cnblogs.com/JackyXu1981/articles/1287910.html AOS Clustering on one Server AOS Clust ...
- 第三讲JdbcRealm及Authentication Strategy
1.使用shiro框架来完成认证工作,默认情况下使用的是IniRealm.如果需要使用其他Realm,那么需要进行相关的配置. 2.ini配置文件讲解: [main] section是你配置应用程序的 ...
- Simple Vedio Intercom System
I. Deployment / Architecture Block Diagram II. Resources Used sip proxy server + sip user agent 1. ...
- Jmeter接口测试---加解密
1.加解密的jar包放到jmeter的lib/ext目录下. 项目打jar包参考https://www.cnblogs.com/fulucky/p/9436229.html 2.在测试计划---> ...
- psexec远程重启服务器
1 使受控机器支持远程psexec 管理 暂参照其他教程 2 打开远程命令行 3 重启服务执行net命令 停止远程桌面 net stop termservice 启动远程桌面 net start te ...
- vue中select的使用以及select设置默认选中
简介 今天写pc端引入vue,遇到了一个问题,就是我循环出select内的数据以后,发现原本默认显示第一条的select框变成了空白,要选择后才有显示,结果查了好多文档,讲的都不是很清楚,后来看到一句 ...
- django权限之二级菜单
遗漏知识点 1.构建表结构时,谁被关联谁就是主表,在层级删除的时候,删除子表的时候,主表不会被删除,反之删除主表的话,字表也会被删除, 使用related_name=None 反向查询,起名用的 ...
- maven之assembly插件
传送门 https://blog.csdn.net/WANGYAN9110/article/details/38646677/ http://blueram.iteye.com/blog/168407 ...