【2015合肥网络赛】(没有补完)

12 篇文章 0 订阅
5 篇文章 0 订阅
HDU 5484 Monitor the Alpacas
HDU 5485 The Relationship in Club
HDU 5486 Difference of Clustering
HDU 5487 Difference of Languages
HDU 5488 Shape
HDU 5489 Removed Interval
HDU 5490 Simple Matrix

【HDU 5491 The Next】

这个题目应该是这场比赛里面最简单的,但是很烦,一不小心就会错

题意是给你三个数  D s1  s2  在比D大的是中找出最小的数,它的二进制中所包含的1的个数在s1~s2中间

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
#define ll __int64
ll p[40];
int vis[40],v[40];
void init()
{
    p[0]=1;
    ll ans=1;
    for(int i=1;i<=32;i++)
    {
        ans*=2;
        p[i]=ans;
    }
}
int main()
{
    init();
    int t,cas=1;
    scanf("%d",&t);
    while(t--)
    {
        ll d;
        int s1,s2;
        memset(vis,0,sizeof(vis));
        scanf("%I64d%d%d",&d,&s1,&s2);
        int sum=0,l=0;
        ll sd=0;
        for(int i=0;i<=32;i++)
        {
            if(d<p[i]) break;
            if(d&p[i]) 
            {
                vis[i]=1;
                sum++;
            }
            l++;
        }
        if(sum<s1)
        {
            int res=s1-sum;
            for(int i=0;i<l;i++)
            {
                if(vis[i]==0 && res>0)
                {
                    vis[i]=1;
                    res--;
                }
                if(vis[i]==1) sd+=p[i];
            }
        }
        else
        {
            for(int i=0;i<l;i++)
            {
                int s=sum;
                int flag=0;
                if(vis[i]==0)
                {
                    for(int j=0;j<l;j++) v[j]=vis[j];
                    flag=1;
                    v[i]=1;
                    s++;
                    int res=0;
                    for(int j=i-1;j>=0;j--)
                    {
                        if(v[j]==1) res++;
                    }
                    res=s-res;
                    if(res>s2) continue;
                    if(s1>res) res=s1-res;
                    else res=0;
                    for(int j=0;j<i;j++)
                    {
                        if(res>0)
                        {
                            v[j]=1;
                            res--;
                            continue;
                        }
                        if(res==0)
                        {
                            v[j]=0;
                        }
                    }
                    s=s1;
                }
                if(s>=s1 && s<=s2 && flag==1) 
                {
                    for(int j=0;j<32;j++) vis[j]=v[j];
                    break;
                }
                if(i==l-1) l++;
            }
            for(int i=0;i<l;i++)
            {
                if(vis[i]==1) sd+=p[i];
            }
        }
        printf("Case #%d: %I64d\n",cas++,sd);
    }
    return 0;
}


【HDU 5492 Find a path】

赛后补的第一个题目

题意是在n*m的矩阵中,找出一条路,起点是(1,1,),终点是(n,m),找出的路要找出以下公式的最小值,Ai表示矩阵上的点的值,Aavg是这条路上点的平均值(N+M1) N+M1i=1(AiAavg)2

其实把这个公式化简一下就知道这个公式的值必定是一个整数,不可能是小数

化简后的公式是(n+m-1)*(A1^2+A2^2+A3^2+……An^2)-(A1+A2+A3+……+An)^2

记Sn=A1+A2+A3+……+An,那么Sn^2=Sn-1^2+2*Sn-1*Ai+Ai*Ai

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
#define maxn 0x3f3f3f3f
int a[35][35];
int dp[35][35][1000];
int s[35][35],d[35][35];
int main()
{
	int t;
	scanf("%d",&t);
	int cas=1;
	while(t--)
	{
		int n,m;
		scanf("%d%d",&n,&m);
		memset(dp,0,sizeof(dp));
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
			{
				scanf("%d",&a[i][j]);
				s[i][j]=max(s[i-1][j],s[i][j-1])+a[i][j];
				d[i][j]=min(d[i-1][j],d[i][j-1])+a[i][j];
				for(int k=d[i][j];k<=s[i][j];k++)
				{
					dp[i][j][k]=maxn;
				}
			}
		}
		dp[1][1][a[1][1]]=(n+m-1)*a[1][1]*a[1][1]-a[1][1]*a[1][1];
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
			{
				for(int k=d[i][j];k<=s[i][j];k++)
				{
					if(dp[i][j][k]==maxn) continue;
					if(i+1<=n) dp[i+1][j][k+a[i+1][j]]=min(dp[i+1][j][k+a[i+1][j]],dp[i][j][k]+(n+m-1)*a[i+1][j]*a[i+1][j]-2*k*a[i+1][j]-a[i+1][j]*a[i+1][j]);
					if(j+1<=m) dp[i][j+1][k+a[i][j+1]]=min(dp[i][j+1][k+a[i][j+1]],dp[i][j][k]+(n+m-1)*a[i][j+1]*a[i][j+1]-2*k*a[i][j+1]-a[i][j+1]*a[i][j+1]);
				}
			}
		}
		int minx=maxn;
		for(int i=d[n][m];i<=s[n][m];i++)
		{
			minx=min(minx,dp[n][m][i]);
		}
		printf("Case #%d: %d\n",cas++,minx);
	}
	return 0;
} 


【HDU 5493 Queue】

(N+M1)N+M1i=1(AiAavg)2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值