zoukankan      html  css  js  c++  java
  • zzuli2504: 建国的签到活动二(dfs)

    http://acm.zzuli.edu.cn/problem.php?id=2504

    题目描述

        建国发现在某宝上即将开始第二波签到活动,这次签到活动会进行n天。这次活动的积分计算方法和上一次活动一样,积分是根据你连续签到的第一天和最后一天计算的。主办方会给你一个积分表,表中会给出所有的a[i][j](a[i][j]表示第i天到第j天全都签过到,且第i-1天与第j+1天没有签到时你可以得到的积分,若不满足所有条件则无法获得该积分)。建国吸取了上一次活动的经验,决定先计划一下自己哪天签到,哪天不签,以便得到更多的积分,你能帮建国计算出他最多可以得到的积分吗?

    输入

    第一行输入一个正整数n,表示活动的天数。(1 <= n <= 15)
    接下来输入n行n列整数,第i行j列表示a[i][j]。(当i>j时,a[i][j]没有实际意义,用-1来表示无意义。当i<=j时,1 <= a[i][j] <= 1000)

    输出

    输出建国最多可以得到的总积分和可以得到最多积分的方案数,两个整数之间用空格间隔。

    样例输入 Copy

    5
    5 4 3 2 1
    -1 4 3 2 1 
    -1 -1 3 2 1
    -1 -1 -1 2 1
    -1 -1 -1 -1 1

    样例输出 Copy

    9 1

    提示

    对于样例,第1,3,5天签到时,可以最多得到9积分。只有这一种方案可以得到最多的9积分。

    题目数据较小,深搜跑一遍即可。

    #include<stdio.h>
    #define N 20
    int ans=0,temp=0,n;
    int a[N][N],s[N];
    void dfs(int m)
    {
    	int i,sum=0,j,t;
    	for(i=0; i<2; i++)
    	{
    		s[m] = i;
    		if(m == n)
    		{
    			sum=0;	
    			for(j=1; j<=n+1 ;j++)
    				if(s[j] == 1)
    					break;
    			t=j;
    			for(; j<=n+1; j++)
    			{
    				if(s[j] == 0)
    				{
    					sum+=a[t][j-1];
    					while(j<=n)
    					{
    						j++;
    						if(s[j] == 1)
    							break;
    					}		
    					t=j;
    				}
    			}	
    			if(sum>ans)
    			{
    				ans = sum;
    				temp = 1;
    			}	
    			else if(sum == ans)
    				temp++;			
    		}
    		else
    		 	dfs(m+1);
    	}
    	return ;
    }
    int main()
    {
    	int i,j;
    	scanf("%d", &n);
    	for(i=1; i<=n; i++)
    		for(j=1; j<=n; j++)
    			scanf("%d", &a[i][j]);
    	dfs(1);
    	printf("%d %d
    ", ans, temp);
    	return 0;
    } 
  • 相关阅读:
    POJ2155 Matrix 【二维线段树】
    BZOJ4785 [Zjoi2017]树状数组 【二维线段树 + 标记永久化】
    B1027 打印沙漏
    Tomcat无法成功启动——双击startup.bat闪退
    MySQL在cmd命令行查看端口号
    1009 说反话(类似回文字符串)
    除基取余法,
    日期差值
    怎么把VS里的scanf_s换成scanf
    联想小新潮怎么修改fn热键以及怎么进入bios状态
  • 原文地址:https://www.cnblogs.com/zyq1758043090/p/11852818.html
Copyright © 2011-2022 走看看