zoukankan      html  css  js  c++  java
  • UVA 1073 Glenbow Museum

    https://vjudge.net/problem/UVA-1073

    题目

    对于一个边平行于坐标轴的多边形,我们可以用一个由R和O组成的序列来描述它:从某个顶点开始按照逆时针顺序走,碰到一个90°的内角(也就是左转)记R;碰到一个270°的内角(右转)记O。这样的序列称为角度序列。由于没有指定边长,所以边长任意。

    现在给定正整数L,求有多少个长度为L的角度序列至少可以对应一个星型多边形(即多边形中存在一个点可以看到多边形边界上的每一个点)。

    注意,一个多边形有多条序列与之对应,比如RRORRORRORRO=RORRORRORROR=ORRORRORRORR

    $1leqslant Lleqslant 1000$

    题解

    题目的条件可以推出R比O多4个,$Rightarrow$:首先摆好4个R,然后剩下的边方向都不变,$Leftarrow$:从完成的部分可以选出4个R,然后剩下的方向都不变。

    由于是星形,不能出现OO

    设$dp[l][Delta][s][t]$为长度为$l$,开始为$s$,结束为$t$,$R-O=Delta$的序列个数

    答案是$dp[L][4][R][R]+dp[L][4][R][O]+dp[L][4][O][R]$,因为[O][O]会导致方向改变。

    AC代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define REP(i,a,b) for(int i=(a); i<(b); i++)
    #define REPE(i,a,b) for(int i=(a); i<=(b); i++)
    #define PERE(i,a,b) for(int i=(a); i>=(b); i--)
    using namespace std;
    typedef long long ll;
    ll dp[1007][7][2][2]; //-1 0 1 2 3 4 5
    int main() {
    	memset(dp,0,sizeof dp);
    	dp[1][2][1][1]=1; //r-o
    	dp[1][0][0][0]=1;
    
    	REPE(l,2,1000) {
    		dp[l][0][0][0]=dp[l-1][1][0][1];
    		dp[l][0][1][0]=dp[l-1][1][1][1];
    		REP(i,1,6) {
    			dp[l][i][0][0]=dp[l-1][i+1][0][1];
    			dp[l][i][0][1]=dp[l-1][i-1][0][0]+dp[l-1][i-1][0][1];
    			dp[l][i][1][0]=dp[l-1][i+1][1][1];
    			dp[l][i][1][1]=dp[l-1][i-1][1][0]+dp[l-1][i-1][1][1];
    		}
    		dp[l][6][0][1]=dp[l-1][5][0][0]+dp[l-1][5][0][1];
    		dp[l][6][1][1]=dp[l-1][5][1][0]+dp[l-1][5][1][1];
    
    	}
    	int L, kase=0;
    	while(~scanf("%d", &L) && L) {
    		printf("Case %d: ", ++kase);
    		if((L&1) || L<4) {
    			puts("0");
    			continue;
    		}
    		ll ans=dp[L][5][0][1]+dp[L][5][1][0]+dp[L][5][1][1];
    		printf("%lld
    ", ans);
    	}
    }
    
  • 相关阅读:
    密码等级
    ie兼容透明
    分割线
    支付宝银行判断接口
    date只能选择今天之后的时间js
    离开页面之前提示,关闭,刷新等
    使用 Linux 系统的常用命令
    C#窗体简单增删改查
    1
    二维数组
  • 原文地址:https://www.cnblogs.com/sahdsg/p/12643625.html
Copyright © 2011-2022 走看看