USACO 2006 November Gold

POJ 3253 Fence Repair STL堆操作

我想说,STL里堆是我目前见到最蛋疼的操作。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <utility>
#include <vector>
#include <queue>
#include <map>
#include <set>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)>(y)?(y):(x))

using namespace std;

int n,a[20005];

int main()
{
    scanf("%d",&n);
    for(int i=0; i<n; i++)
        scanf("%d",&a[i]);
    vector< int > v(a,a+n);
    make_heap(v.begin(),v.end(),greater< int >());
    long long ans=0;
    for(int i=1; i<=n-1; i++)
    {
        long long tmp=v.front();
        pop_heap(v.begin(),v.end(),greater< int >());
        v.pop_back();
        tmp+=v.front();
        pop_heap(v.begin(), v.end(),greater< int >());
        v.pop_back();
        v.push_back(tmp);
        push_heap(v.begin(),v.end(),greater< int >());
        ans+=tmp;
        printf("%d\n", tmp);
    }
    printf("%lld\n",ans);
    return 0;
}

POJ 3254 Corn Fields 状态压缩递推

uc[]表示相邻两位不同时为1的情况,377种,因此n*377^2即可

注意,位运算优先级是低于==的!

#include <cstdio>
#include <cstring>
#define MOD 100000000

int n,m,a[20],k;
int uc[500],all;
int f[20][5000];

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=0; i<n; i++)
        for(int j=0; j<m; j++)
        {
            scanf("%d",&k);
            a[i]=(a[i]<<1)+k;
        }
    for(int i=0; i<(1<<m); i++)
    {
        int tmi=i,flag=0;
        while(tmi)
        {
            if((tmi&3)==3) flag=1;
            tmi>>=1;
        }
        if(!flag)
        {
            uc[all++]=i;
            if((i|a[0])==a[0])
                f[0][i]=1;
        }
    }

    for(int i=1; i<n; i++)
        for(int j=0; j<all; j++)
        if((a[i]|uc[j])==a[i])
        {
            for(int k=0; k<all; k++)
            if(!(uc[j]&uc[k]))
            {
                f[i][uc[j]]=(f[i][uc[j]]+f[i-1][uc[k]])%MOD;
            }
        }

    int ans=0;
    for(int j=0; j<all; j++)
        ans=(ans+f[n-1][uc[j]])%MOD;
    printf("%d\n", ans);
    return 0;
}

POJ 3255 A*算法求第k短路

第一次接触A*,了解了下。

—————————————————维基百科————————————————————————————

如果以 g(n)表示从起点到任意顶点n的实际距离,h(n)表示任意顶点n到目标顶点的估算距离,那么 A*算法的公式为:f(n)=g(n)+h(n)。 这个公式遵循以下特性:

  • 如果h(n)为0,只需求出g(n),即求出起点到任意顶点n的最短路径,则转化为单源最短路径问题,即Dijkstra算法
  • 如果h(n)<=“n到目标的实际距离”,则一定可以求出最优解。而且h(n)越小,需要计算的节点越多,算法效率越低。

—————————————————————————————————————————————————

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <utility>
#include <vector>
#include <queue>
#include <map>
#include <set>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)>(y)?(y):(x))
#define INF 0x3f3f3f3f

using namespace std;

struct Edge
{
    int y,w,ne;
}e[200005];

int x,y,w,n,m;
int be[5005],all;
int h[5005];
bool vis[5005];

struct Point
{
    int x,g;
    bool operator < (const Point T) const
    {
        return g+h[x]>T.g+h[T.x];
    }
};

void add(int x, int y, int w)
{
    e[all].y=y;
    e[all].w=w;
    e[all].ne=be[x];
    be[x]=all++;
}

void SPFA(int s)
{
    queue< int > q;
    for(int i=0; i<=n; i++)
    {
        h[i]=INF;
        vis[i]=0;
    }
    h[s]=0;
    vis[s]=1;
    while(!q.empty())
        q.pop();
    q.push(s);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=be[u]; i!=-1; i=e[i].ne)
        {
            int v=e[i].y;
            if(h[v]>h[u]+e[i].w)
            {
                h[v]=h[u]+e[i].w;
                if(!vis[v])
                {
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
}

int Astar(int s, int t, int k)
{
    SPFA(t);
    priority_queue< Point > q;
    while(!q.empty())
        q.pop();
    memset(vis,0,sizeof(vis));
    Point cur,nxt;
    cur.x=s;
    cur.g=0;
    q.push(cur);
    while(!q.empty())
    {
        cur=q.top();
        q.pop();
        if(cur.x==t && !--k)
            return cur.g;
        for(int i=be[cur.x]; i!=-1; i=e[i].ne)
        {
            nxt.x=e[i].y;
            nxt.g=cur.g+e[i].w;
            q.push(nxt);
        }
    }
    return -1;
}

void init()
{
    all=0;
    memset(be,-1,sizeof(be));
}

int main()
{
    scanf("%d%d",&n,&m);
    init();
    for(int i=0; i<m; i++)
    {
        scanf("%d%d%d",&x,&y,&w);
        add(x,y,w);
        add(y,x,w);
    }
    printf("%d\n",Astar(1,n,2));
    return 0;
}

时间: 2024-08-01 16:12:48

USACO 2006 November Gold的相关文章

[Poj3261] [Bzoj1717] [后缀数组论文例题,USACO 2006 December Gold] Milk Patterns [后缀数组可重叠的k次最长重复子串]

和上一题(POJ1743,上一篇博客)相似,只是二分的判断条件是:是否存在一段后缀的个数不小于k 1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cmath> 7 #include <ctime> 8 #include <map&

POJ 3261 USACO 2006 December Gold Milk Patterns

题目大意:给出一个字符串,求出出现过k次以上的最长的子串(可重叠). 思路:现弄出来sa数组和height数组,之后就是判断每个长度为k的height数组的区间中最小的数字的最大值了.为什么好多人都二分了?这只要单调队列扫一次就行了啊.. CODE: #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #def

USACO 2008 November Gold Cheering up the Cows /// MST oj24381

题目大意: 输入n,p:n个点,p条路 接下来n行输入c[]:在各个点需要花费的时间 接下来p行输入u,v,w:u点到v点的路需要花费时间w 求经过所有点且最后回到起点的最少花费时间 https://blog.csdn.net/HY_VFenux/article/details/68954199 将每条边的权值存为 路径花费*2+两端点花费 Kruscal求MST 最后加上开始位于起点的花费 即各个点中最少花费的一个 #include <bits/stdc++.h> #define INF 0

[USACO 2012 Mar Gold] Large Banner

传送门:http://www.usaco.org/index.php?page=viewproblem2&cpid=127 又是一道这种题目,遇到一次跪一次,这次终于硬着头皮看懂了题解,但是谢了代码之后还是wa了3个点(共20个),实在是找不出哪里错了,略烦... 题解真的不想写了,贴个链接叭... http://blog.csdn.net/kanosword/article/details/52585972 这道题比较冷门,官方题解看得不是太懂,上面那个链接讲得比较清楚.

bzoj2581 [USACO 2012 Jan Gold] Cow Run【And-Or Tree】

传送门1:http://www.usaco.org/index.php?page=viewproblem2&cpid=110 传送门2:http://www.lydsy.com/JudgeOnline/problem.php?id=2581 这题我一看就知道自己不会了,只想了个O(2^n * 2 ^ n)即O(2 ^ 2n)的大暴力,也懒得打了,果断看solution. 看了之后惊呆了,看到了一种从未见过,闻所未闻的树叫做And-Or Tree,百度了一下,并没有官方中文翻译,姑且叫他"

【BZOJ1229】【USACO 2008 Nov Gold】 4.Toys sadstory 三分+贪心

sad story:我们自己oj的数据貌似有点问题.标程WA了5% 题解: 复制去Google翻译翻译结果 首先引一下VFK神犇的证明来证明一下这道题是三分.. { 我来告诉你世界的真相 = = 因为这题能最小费用最大流 每次最短路长度不降 所以是单峰的 最短路长度就是差分值.. 所以一阶导不降.. 是不是简单粗暴 你要证函数是单峰的. 当然是证斜率什么的 } 三分完初始买了多少个玩具,然后就是贪心. 首先我想说这个贪心真动规.虽然它真的是贪心. 首先先说一种错误的贪心. 就是从前往后扫,优先用

USACO 2011 Jan Gold 3. Roads and Planes

题意: 给出一个n个结点m条边有向图,可能有负权边: 但是存在负权边a->b则不会有某个路径可以从b到a: 求一个源点s到所有点的最短路(无解输出"NO PATH"): n<=25000,m<=150000: 题解: 高高兴兴的写了一发spfa,O(km)嘛: 然后就TLE了,这题丧心病狂的把spfa卡掉了: 这时候理所当然的想到了dij+heap,写到一半想起来不支持负权边: 所以这个不是一个简单的单源最短路问题: 题中有一个重要条件就是负权边不会回去: 我本以为只

BZOJ 1717 Usaco 2006 Dec 产奶模式

1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1557  Solved: 847[Submit][Status][Discuss] Description 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的质量,但连续的若干天的质量有很多重叠.我们称之为一个"模式". John的牛奶按质量可以被赋予一个0到10000

【POJ3659】【USACO 2008 Jan Gold】 3.Cell Phone Network 树上最小支配集/贪心 两种做法

题意:求树上最小支配集 最小支配集:点集,即每个点可以"支配"到相邻点,求最少点数可以使所有点被支配. 图上的最小支配集是NP的,但是树上的可以DP做,是O(n)的. 暴力做就好了, f[i]表示此 点被选时的子树全支配的最小代价 g[i]表示其父亲节 点被选时的子树全支配的最小代价 h[i]表示其某子节 点被选时的子树全支配的最小代价 然后暴力转移. (v是子节点) f[x]=∑(min(f[v],min(g[v],h[v])))+1; g[x]=∑(min(f[v],h[v]));