2014多校联合-第七场

1005: ( Stupid Tower Defense )

由题意我们很明显可以知道,红色的塔放在最后面是最优的。

假如前i个塔,放j个绿塔,i-j个蓝塔。那么无论前i个塔的顺序怎么放,对后面的塔造成的影响是完全相同的。

dp[i][j]:前i个塔,放j个绿塔,能获得的最大价值。

dp[i][j]=max(dp[i-1][j-1]+当前塔放绿塔获得的能量值,dp[i-1][j]+当前塔放蓝塔获得的能量值);

#include <iostream>
#include<stdio.h>
#include<vector>
#include<queue>
#include<stack>
#include<string.h>
#include<algorithm>
using namespace std;
#define LL __int64
#define lcm(a,b) (a*b/gcd(a,b))
LL intx(LL num,LL t,LL x,LL chi)
{
    return num*t*(x+chi);
}
LL inty(LL num,LL t,LL y,LL chi)
{
    return (t)*y*(num-1)*num/2+chi*t*num;
}
LL intz(LL num,LL t,LL z,LL chi)
{
    return chi*(num*t+(num-1)*num/2*z);
}
LL dp[1501][1501];
int main()
{
    LL n,x,y,z,t,cas,i,j;
    scanf("%I64d",&cas);
    LL nn = 1;
    while(cas--)
    {
        scanf("%I64d%I64d%I64d%I64d%I64d",&n,&x,&y,&z,&t);
        LL ans = t*x*n;
        LL sum;
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
        {
            dp[i][0]=dp[i-1][0];
            ans=max(ans,dp[i][0]+intx(n-i,t+i*z,x,0));
            for(int j=1;j<=i-1;j++)
            {
                dp[i][j]=max(dp[i-1][j-1]+inty(1,t+z*(i-j),y,(j-1)*y),
                             dp[i-1][j]+intz(1,t+z*(i-1-j),z,j*y));
                ans=max(ans,dp[i][j]+intx(n-i,t+(i-j)*z,x,j*y));
            }
            dp[i][i]=dp[i-1][i-1]+inty(1,t,y,(i-1)*y);
            ans=max(ans,dp[i][i]+intx(n-i,t,x,i*y));

        }
        printf("Case #%I64d: %I64d\n",nn++,ans);
    }
    return 0;
}

1007: ( Magical Forest )

反正各种离散化,然后标记本行原先属于那一行,之后乱七八糟的搞一下就可以了。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <assert.h>
#include<iostream>
#include<vector>
using namespace std;
#define MAXN 10050
#define LL __int64
vector<int>vecx,vecxx;
vector<int>vecy,vecyy;
struct list
{
    int x;
    int y;
    int c;
    friend bool operator <(const list &a,const list &b)
    {
        if(a.x!=b.x)return a.x<b.x;
        else return a.y<b.y;
    }
}node[110000];
int fx[110000];
int fy[110000];
int k;
int find(int x,int leap)
{
   // cout<<x<<" "<<leap<<endl;
    if(leap==0)
    {
        int l=0;
        int r=vecx.size();
        int mid=(l+r)/2;
        while(l<r)
        {
            //cout<<l<<" "<<r<<" "<<mid<<" "<<vecx[mid]<<endl;
            if(vecx[mid]<x)l=mid+1;
            else r=mid;
            mid=(l+r)/2;

        }
        if(mid!=vecx.size()&&vecx[mid]==x)return mid+1;
        else return 0;
    }
    if(leap==1)
    {
        int l=0;
        int r=vecy.size();
        int mid=(l+r)/2;
        while(l<r)
        {
            if(vecy[mid]<x)l=mid+1;
            else r=mid;
            mid=(l+r)/2;
        }
        if(mid!=vecy.size()&&vecy[mid]==x)return mid+1;
        else return 0;
    }
    return 0;
}
void out(int x,int y)
{
  //  cout<<x<<" -- "<<y<<endl;
    if(x==0||y==0)
    {
        cout<<"0"<<endl;
        return;
    }
    int l=1;
    int r=k+1;
    int mid=(l+r)/2;
    while(l<r)
    {
        if(node[mid].x<x)l=mid+1;
        else if(node[mid].x>x)r=mid;
        else if(node[mid].x==x)
        {
            if(node[mid].y<y)l=mid+1;
            else if(node[mid].y>=y)r=mid;
        }
        mid=(l+r)/2;
    }
    if(node[mid].y==y&&node[mid].x==x&&mid<=k)
    {
        cout<<node[mid].c<<endl;
    }
    else cout<<"0"<<endl;
}
int main()
{
    int W,cas;
    int n,m;
    scanf("%d",&W);
    cas=0;
    while(W--)
    {
        cas++;
        scanf("%d%d%d",&n,&m,&k);
        vecx.clear();
        vecxx.clear();
        vecy.clear();
        vecyy.clear();
        fx[0]=fy[0]=0;
        for(int i=1;i<=k;i++)
        {
            fx[i]=i;
            fy[i]=i;
            scanf("%d%d%d",&node[i].x,&node[i].y,&node[i].c);
            vecxx.push_back(node[i].x);
            vecyy.push_back(node[i].y);
        }
        sort(vecxx.begin(),vecxx.end());
        sort(vecyy.begin(),vecyy.end());
        vecx.push_back(vecxx[0]);
        vecy.push_back(vecyy[0]);
        for(int i=1;i<k;i++)
        {
            if(vecxx[i]!=vecxx[i-1])vecx.push_back(vecxx[i]);
            if(vecyy[i]!=vecyy[i-1])vecy.push_back(vecyy[i]);
        }
        for(int i=1;i<=k;i++)
        {
            node[i].x=find(node[i].x,0);
            node[i].y=find(node[i].y,1);
        }
        sort(node+1,node+k+1);
        printf("Case #%d:\n",cas);
        int q,x,a,b;
        scanf("%d",&q);
        while(q--)
        {
            scanf("%d%d%d",&x,&a,&b);
            if(x==1)
            {
                a=find(a,0);
                b=find(b,0);
                swap(fx[a],fx[b]);
            }
            if(x==2)
            {
                a=find(a,1);
                b=find(b,1);
                swap(fy[a],fy[b]);
            }
            if(x==3)
            {
                a=find(a,0);
                b=find(b,1);
                out(fx[a],fy[b]);
            }
        }
    }
    return 0;
}

1010:FSF’s game

由题意我们可以知道,对于任意一对长为n,宽为m的长方形,我们可以得到的分数为:

假如gcd(n,m)=2^x*3^y.....,.假如d为n的因子

(N,M)=n*m/(gcd(n,m))*(2^0+2^1+..+2^x)*(3^0+3^1+...+3^y);

很明显当n固定时,在m等于1~n的时候,m/(gcd(n,m))*(2^0+2^1+..+2^x)*(3^0+3^1+...+3^y)的总和等于所有的d*(d+1)/2的总和

那就可以预处理一个数因子的总和,然后直接递推式就好。

#include <iostream>
#include<stdio.h>
#include<vector>
#include<queue>
#include<stack>
#include<string.h>
#include<algorithm>
using namespace std;
#define maxn 550000
#define UI unsigned int
#define N 550000
#define LL __int64
UI ans[maxn];
UI use[maxn];
void mk()
{
    memset(use,0,sizeof(use));
    for(UI i=1;i<maxn;i++)
    {
        LL now=(LL)i*((LL)i+(LL)1)/(LL)2;
        UI add=now;
        for(UI j=i;j<maxn;j+=i)
        {
            use[j]=use[j]+add;
        }
    }
}
void init()
{
    mk();
    ans[1]=1;
    for(UI i=2;i<maxn;i++)
    {
        ans[i]=ans[i-1]+use[i]*(UI)i;
    }
}
int main()
{
    int T,n;
    init();
    scanf("%d",&T);
    int cas=0;
    while(T--)
    {
        cas++;
        scanf("%d",&n);
        printf("Case #%d: %u\n",cas,ans[n]);
    }
    return 0;
}

2014多校联合-第七场

时间: 2024-11-08 06:03:19

2014多校联合-第七场的相关文章

2014多校联合-第六场

最近这两场好无奈啊... 今天这场最后30分钟敲1001,压力倍增,虽然思路比较明确,但是代码打起来不怎么容易. 但是还是好在25分钟左右debug结束.提交wa,再提交,依然WA.......最后5分钟,还是没有AC掉. 一开始以为是精度问题,后来才sb的发现原来数组开小了. 在压力环境下保证代码的效率和质量真不是一件容易的事情.不过数组开小了,真是不可原谅. 1001:Map 题目相当于几条链表.把链表排成几行. 然后枚举每一列的状态会被操作多少次. 然后把和累加起来,然后直接除以状态总数.

2014多校联合-第八场

1001:2048 很明显,一开始看错题了...sad 这题目我感觉挺卡时间的... dp[i][j]:在选择2^i的时候,选择的和为j*2^i到(j+1)*2^i-1时候的情况. #include <iostream> #include<stdio.h> #include<vector> #include<queue> #include<stack> #include<string.h> #include<algorithm&

2014多校联合-第五场

1001:Inversion 模版题,求逆序数对.有多少逆序数对,就可以剪掉多少. 1003:Least common multiple 对于每一个子集,lcm为2的a的最大值次方*3的b的最大值次方. 所以我们只需要求出以某个b为b的最大值的时候,a的最大值的分布情况即可. 我们先把b从小到大排序. 对于某一个b,我门只需要求出之前出现过的a比当前a小的数量为x: 那么就可知对于这些a的子集,为2^x个,并且,每个子集a的最大值都为当前a. 我么还需要求出对于大于当前a的a有多少个比a小的数,

2014多校联合训练第一场(组队训练)

这是我.potaty.lmz第二次训练,毕竟经验不足,加上水平不够,导致我们各种被碾压. A - Couple doubi: 这道题是道比较水的数论.但我们都没想出来要怎么做.后来是potaty提议打个表看看,然后lmz打出表后发现了规律.我还没细看,待研究后再补全. D - Task: 这道题一看就知道是个贪心(现在只要是有deadline的题我都觉得是贪心了).虽然想出来了,但还是不会严格证明为什么只要取满足task的且y最小(y相等时x最小)的machine就行了. 我的做法是把所有mac

2014多校联合七(HDU 4937 HDU 4938 HDU 4939 HDU 4941)

好几天没写题解了- 都怪我太弱  补题补不动- HDU 4937 Lucky Number 题意:一个数字如果只有3456这四种数字组成  那么这个数字是幸运的  问  给出一个x  它在几种进制下是幸运的  如果无穷输出-1 思路: 分类讨论  如果x是3或4或5或6  那么一定有无穷个进制满足(从十进制开始-)  直接输出-1 除去上述情况  那么我们可以将一个数字写成这样 a0 + a1*base + a2*base^2 +... = x 那么如果base的最高次只有1次或2次时  就是简

hdu 4865 Peter&amp;#39;s Hobby(2014 多校联合第一场 E)

Peter's Hobby Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 545    Accepted Submission(s): 237 Problem Description Recently, Peter likes to measure the humidity of leaves. He recorded a leaf

2014多校联合第一场

1001:Couple doubi 暴力打表找规律可知,对于任意的p. (1^i+2^i+...+(p-1)^i)%p={ 非0     ,i%(p-1)==0 0        ,  i%(p-1)!=0 } 所以,结果就很显然了. #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<stdlib.h> #include<c

hdu 4865 Peter&#39;s Hobby(2014 多校联合第一场 E)

题意:已知昨天天气与今天天气状况的概率关系(wePro),和今天天气状态和叶子湿度的概率关系(lePro)第一天为sunny 概率为 0.63,cloudy 概率 0.17,rainny 概率 0.2.给定n天的叶子湿度状态,求这n天最可能的天气情况 分析:概率dp设 dp[i][j] 表示第i天天气为j的最大概率,pre[i][j]表示第i天天气最可能为j的前一天天气,dp[i][j]=max(dp[i-1][k]+log(wePro[k][j])+log(lePro[j][lePos[i]]

hdu 4869 Turn the pokers (2014多校联合第一场 I)

Turn the pokers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1265    Accepted Submission(s): 465 Problem Description During summer vacation,Alice stay at home for a long time, with nothing t