zoukankan      html  css  js  c++  java
  • [CSP-S模拟测试]:装饰(状压DP)

    题目传送门(内部题114)


    输入格式

      第一行一个正整数$n$。
      接下来一行$n-1$个正整数,第$i$个数为$f_{i+1}$。
      接下来一行$n$个数,若第$i$个数为$0$则表示林先森希望$i$号点的彩灯是关闭状态,若第$i$个数为$1$则表示林先森希望$i$号点的彩灯是开启状态。


    输出格式

      输出一行一个整数,表示林先森最少需要几秒才能看到他期望看到的树。


    样例

    样例输入1:

    4
    1 2 3
    0 1 1 0

    样例输出1:

    2

    样例输入2:

    7
    1 1 2 2 3 3
    0 1 1 1 0 0 1

    样例输出2:

    3


    数据范围与提示

    样例解释:

      第一个样例:
      $ullet$第一秒林先森拨动$3$号点的开关,彩灯状态变为$0 0 1 0$。
      $ullet$第二秒林先森什么也不做,彩灯状态变为$0 1 1 0$,满足要求。
      第二个样例:
      $ullet$第一秒林先森拨动$4$号点的开关,彩灯状态变为$0 0 0 1 0 0 0$。
      $ullet$第二秒林先森拨动$7$号点的开关,彩灯状态变为$0 1 0 1 0 0 1$。
      $ullet$第三秒林先森拨动$1$号点的开关,与$2$号点传递的拨动效果抵消,彩灯状态变为$0 1 1 1 0 0 1$,满足要求。

    数据范围:

      对于$30\%$的数据,$nleqslant 8$。
      对于另$30\%$的数据,林先森希望看到所有彩灯都被点亮。
      对于$100\%$的数据,$1leqslant nleqslant 16$。


    题解

    数据范围较小,考虑状压$DP$。

    因为答案最大为$n$,所以我们可以枚举秒数。

    设$dp[i][state]$表示第$i$秒,状态为$state$是否可行。

    因为开关只与正负是否相同有关,而与具体是开还是关无关,所以我们可以假设最终的状态为起始状态,然后想办法转移到$0$状态(其实就是代码复杂度低一点而已)。

    预处理出来每个点会对其它的点在下一秒做的贡献即可。

    时间复杂度:$Theta(2^nn^2)$。

    期望得分:$100$分。

    实际得分:$100$分。


    代码时刻

    #include<bits/stdc++.h>
    using namespace std;
    int n,state;
    int fa[20],Map[20][20];
    bool dp[20][100000];
    int main()
    {
    	scanf("%d",&n);
    	for(int i=0;i<=n;i++)Map[1][i]=1;
    	for(int i=2;i<=n;i++)
    	{
    		Map[i][0]=1<<(i-1);
    		scanf("%d",&fa[i]);
    		int now=i;
    		for(int j=1;j<=n;j++)
    		{
    			now=fa[now];
    			if(now)Map[i][j]=Map[i][j-1]|(1<<(now-1));
    			else Map[i][j]=Map[i][j-1];
    		}
    	}
    	for(int i=1;i<=n;i++){int x;scanf("%d",&x);state|=x<<(i-1);}
    	dp[0][state]=1;
    	for(int i=0;i<=n;i++)
    	{
    		if(dp[i][0]){printf("%d",i);break;}
    		for(int s=1;s<(1<<n);s++)
    			if(dp[i][s])
    			{
    				dp[i+1][s]=1;
    				for(int j=1;j<=n;j++)
    					dp[i+1][s^Map[j][i]]=1;
    			}
    	}
    	return 0;
    }
    

    rp++

  • 相关阅读:
    js控制两个日期相减
    下拉框只显示最初下拉框中的值和json返回array的交集
    js来进行字符串的转化和小数点后的截取
    js来实现popup的生成,带钟罩,可移动popup,点击body可自动消失
    css块居中
    響應式設計佈局
    pc端手機端自適應佈局方案
    pc端常規頁面實現
    pc端前端和手機端區別
    js字符串轉數組,數組轉字符串
  • 原文地址:https://www.cnblogs.com/wzc521/p/11782687.html
Copyright © 2011-2022 走看看