??xml version="1.0" encoding="utf-8" standalone="yes"?>久久久亚洲国产美女国产盗摄,欧美a级片一区,在线午夜精品自拍http://m.shnenglu.com/ACM-Boy/category/5700.htmlzh-cnSat, 16 Aug 2008 13:31:49 GMTSat, 16 Aug 2008 13:31:49 GMT60PKU 1733 Parity gamehttp://m.shnenglu.com/ACM-Boy/archive/2008/08/15/58919.htmlACM-BoyACM-BoyFri, 15 Aug 2008 03:23:00 GMThttp://m.shnenglu.com/ACM-Boy/archive/2008/08/15/58919.htmlhttp://m.shnenglu.com/ACM-Boy/comments/58919.htmlhttp://m.shnenglu.com/ACM-Boy/archive/2008/08/15/58919.html#Feedback0http://m.shnenglu.com/ACM-Boy/comments/commentRss/58919.htmlhttp://m.shnenglu.com/ACM-Boy/services/trackbacks/58919.html
思\Q?br>    告诉你[a,b]之间1个数的奇偶情况,那么你就可以在a-1和b之间q一条边Q权值就是其奇偶情况。这样一来,比如[1,2]和[3,4]的情况已知,[1,4]的情况也q道了(jin)。当题目l出[a,b]的情冉|Q首先分别从a和b往上找Q找C们的根r1和r2Q如果r1 !=  r2Q表Ca,b之间的奇偶情况还?sh)确定,将r1和r2之间qv来,Ҏ(gu)a(chn)到r1的权倹{b到r2的权值和题目所l的奇偶情况Q设|r1和r2之间的权|以符合题目要求。若r1 == r2Q则表示[a,b]之间情况已确定,Ҏ(gu)a(chn)到r1的权值和b到r2的权|可以判断题目所l的[a,b]的情冉|否ؓ(f)真?br>    其实当时做的时候,q(sh)是很懂,但没惛_E里糊涂的AC?jin)。推荐一下这个网:(x)http://hi.baidu.com/fandywang_jlu/blog/item/b49e40893ddbb0b00f244485.htmlQ这里面介绍q查集挺详细的,q有不少推荐题目Q有些还?sh)?x)做。:(x)P

代码Q?br>
#include <iostream>
#include <map>
using namespace std;

const int MAX = 10005;

int n, p;
int pre[MAX];
int parity[MAX];        //i到目前集合的根的奇偶情况
map<int, int> numIndex;        //用于L?br>
int Find (int x)
{
    if ( pre[x] == -1 )
        return x;
    int f;
    f = Find(pre[x]);
    parity[x] = (parity[x] + parity[pre[x]]) % 2;    //此时pre[x]已指向最l的集合的根
    pre[x] = f;
    return f;
}

bool Query (int x, int y, int odd)
{
    int r1, r2;
    r1 = Find(x);
    r2 = Find(y);
    if ( r1 == r2 )
    {
        if ( (parity[x] + parity[y]) % 2 == odd )
            return true;
        else
            return false;
    }
    else            //只是r1接到r2下面Q这边还可以优化
    {
        pre[r1] = r2;
        parity[r1] = (parity[x] + parity[y] + odd) % 2;
        return true;
    }
}

void Solve ()
{
    int i, x, y, index, idx1, idx2, odd;
    char s[10];
    scanf("%d%d", &n, &p);
    index = 0;
    for (i=0; i<p; i++)
    {
        scanf("%d%d%s", &x, &y, &s);
        x --;
        if ( numIndex.find(x) == numIndex.end() )
            numIndex[x] = index ++;
        idx1 = numIndex[x];
        if ( numIndex.find(y) == numIndex.end() )
            numIndex[y] = index ++;
        idx2 = numIndex[y];
        if ( strcmp(s, "odd") == 0 )
            odd = 1;
        else
            odd = 0;
        if ( Query(idx1, idx2, odd) == false )
        {
            break;
        }
    }
   
    printf("%d\n", i);
}

void Init ()
{
    memset(pre, -1, sizeof(pre));
}

int main ()
{
    Init();
    Solve();

    return 0;
}


ACM-Boy 2008-08-15 11:23 发表评论
]]>
PKU 1639 Picnic Planninghttp://m.shnenglu.com/ACM-Boy/archive/2008/07/30/57547.htmlACM-BoyACM-BoyWed, 30 Jul 2008 11:10:00 GMThttp://m.shnenglu.com/ACM-Boy/archive/2008/07/30/57547.htmlhttp://m.shnenglu.com/ACM-Boy/comments/57547.htmlhttp://m.shnenglu.com/ACM-Boy/archive/2008/07/30/57547.html#Feedback0http://m.shnenglu.com/ACM-Boy/comments/commentRss/57547.htmlhttp://m.shnenglu.com/ACM-Boy/services/trackbacks/57547.html阅读全文

ACM-Boy 2008-07-30 19:10 发表评论
]]>
PKU 1037 A decorative fencehttp://m.shnenglu.com/ACM-Boy/archive/2008/05/20/50507.htmlACM-BoyACM-BoyTue, 20 May 2008 04:45:00 GMThttp://m.shnenglu.com/ACM-Boy/archive/2008/05/20/50507.htmlhttp://m.shnenglu.com/ACM-Boy/comments/50507.htmlhttp://m.shnenglu.com/ACM-Boy/archive/2008/05/20/50507.html#Feedback2http://m.shnenglu.com/ACM-Boy/comments/commentRss/50507.htmlhttp://m.shnenglu.com/ACM-Boy/services/trackbacks/50507.html阅读全文

ACM-Boy 2008-05-20 12:45 发表评论
]]>
PKU 2201 Cartesian Treehttp://m.shnenglu.com/ACM-Boy/archive/2008/04/25/48158.htmlACM-BoyACM-BoyFri, 25 Apr 2008 13:27:00 GMThttp://m.shnenglu.com/ACM-Boy/archive/2008/04/25/48158.htmlhttp://m.shnenglu.com/ACM-Boy/comments/48158.htmlhttp://m.shnenglu.com/ACM-Boy/archive/2008/04/25/48158.html#Feedback0http://m.shnenglu.com/ACM-Boy/comments/commentRss/48158.htmlhttp://m.shnenglu.com/ACM-Boy/services/trackbacks/48158.html阅读全文

ACM-Boy 2008-04-25 21:27 发表评论
]]>
PKU 1018 Communication Systemhttp://m.shnenglu.com/ACM-Boy/archive/2008/04/25/48157.htmlACM-BoyACM-BoyFri, 25 Apr 2008 13:25:00 GMThttp://m.shnenglu.com/ACM-Boy/archive/2008/04/25/48157.htmlhttp://m.shnenglu.com/ACM-Boy/comments/48157.htmlhttp://m.shnenglu.com/ACM-Boy/archive/2008/04/25/48157.html#Feedback0http://m.shnenglu.com/ACM-Boy/comments/commentRss/48157.htmlhttp://m.shnenglu.com/ACM-Boy/services/trackbacks/48157.html 题目来源Q?/span>

PKU 1018 Communication System

 

法分类Q?/span>

枚D+贪心(j)

 

原文Q?/span>

Communication System

Time Limit:1000MS  Memory Limit:10000K

Description

We have received an order from Pizoor Communications Inc. for a special communication system. The system consists of several devices. For each device, we are free to choose from several manufacturers. Same devices from two manufacturers differ in their maximum bandwidths and prices.
By overall bandwidth (B) we mean the minimum of the bandwidths of the chosen devices in the communication system and the total price (P) is the sum of the prices of all chosen devices. Our goal is to choose a manufacturer for each device to maximize B/P.

Input

The first line of the input file contains a single integer t (1 ≤ t ≤ 10), the number of test cases, followed by the input data for each test case. Each test case starts with a line containing a single integer n (1 ≤ n ≤ 100), the number of devices in the communication system, followed by n lines in the following format: the i-th line (1 ≤ i ≤ n) starts with mi (1 ≤ mi ≤ 100), the number of manufacturers for the i-th device, followed by mi pairs of positive integers in the same line, each indicating the bandwidth and the price of the device respectively, corresponding to a manufacturer.

Output

Your program should produce a single line for each test case containing a single number which is the maximum possible B/P for the test case. Round the numbers in the output to 3 digits after decimal point.

Sample Input

1 3

3 100 25 150 35 80 25

2 120 80 155 40

2 100 100 120 110

 

Sample Output

0.649

 

Source

Tehran 2002, First Iran Nationwide Internet Programming Contest

 

 

中文描述Q?/span>

你需要购?/span>nU设备来l一个通信pȝQ每一U设备,又是׃些不同的刉商生的,不同刉商生的同U设备会(x)有不同的带宽和h(hun)根{现在你要在每一个设备的刉商中选一个,使得购买?/span>nU设备,它们带宽的最gh之和的比最大?/span>

 

题目分析Q?/span>

一开始想到的是暴搜Q但是搜索的深度辑ֈ100Q时间肯定是不允许的。想要解册题,必须扑ֈ一个好的查扄略。再x(chng)看这题的特点Q最后的{案Q带宽是选取所有设备中的最|而h(hun)格是选取所有设备的hd。如果某个制造商生的某U设备,它的带宽较高而h(hun)D低,那么选取它的可能性就比较大。再q一步说Q如果所选取?/span>nU设备的带宽的最?/span>b已经定Q那么对于某U设备,我们可以在那些生q种讑֤的,带宽大于{于b的制造商中进行选择。当然是选那个h(hun)格最低的讑֤Q因为答案的分子已经定?/span>bQ所以分母越越好。看来只要枚?/span>bQ再对于每个讑֤贪心(j)的选择最h(hun)格就可以?jin),旉复杂度?f)OQ?/span>mnBQ,B为带宽枚丄数量。但问题又来?jin),应该怎么枚D带宽Q题目中q未l出带宽的取D_(d)如果?/span>0..maxB一个一个枚丄话,既费时又?x)造成q多重复情况Q如果枚N些在输入中出现的两个q箋(hu)带宽之间的|最后的{案是一L(fng)Q。所以我们应该采取某个方法记录输入中出现q的带宽Q?/span>STL中的set是个不错的选择Q,再枚举这些带宽。在枚D中,可能出现q种情况Q枚?/span>bQ选择?/span>nU设备,但选择的所有设备的带宽都大?/span>bQ那么最l用b/price׃是这U情늚正确{案。其实不用担?j),因?f)正确{案一定大?/span>b/price。假设上面这U情늚实际带宽最值是b’Q那个当我们再去枚Db’Ӟ臛_有一个设备的带宽{于b’Q这ơ得到的{案也就是上面那U情늚{案Q所以最l还是能得到正确解?/span>

 

代码Q?/span>

#include <iostream>

#include <map>

#include <set>

#include <climits>

using namespace std;

 

const int MAX = 105;

 

struct Info

{

                int band, price;

};

 

struct Device

{

                int manuNum;

                Info info[MAX];

                map<int, int> minPrice;                 //map[i] = j 表示带宽>=i的最h(hun)格是j

                int minBand, maxBand;

};

 

Device device[MAX];

int deviceNum;

set<int> band;                                                                  //输入中出现过?/span>band

set<int>::iterator start, end;

int maxBand, minBand;                                 //需要枚丄band的最?/span>

 

int cmp( const void *a , const void *b )

{

                Info *c = (Info *)a;

                Info *d = (Info *)b;

                if(c->band != d->band)

                                return d->band - c->band;

                else

                                return c->price - d->price;

}

 

void Input ()

{

                int i, j, max, min;

                band.clear();

                cin>>deviceNum;

                for (i=0; i<deviceNum; i++)

                {

                                device[i].minBand = INT_MAX;

                                device[i].maxBand = -1;

                                cin>>device[i].manuNum;

                                for (j=0; j<device[i].manuNum; j++)

                                {

                                                cin>>device[i].info[j].band>>device[i].info[j].price;

                                                band.insert(device[i].info[j].band);

                                                if ( device[i].info[j].band > device[i].maxBand )

                                                                device[i].maxBand = device[i].info[j].band;

                                                if ( device[i].info[j].band < device[i].minBand )

                                                                device[i].minBand = device[i].info[j].band;

                                }

                                                               

                }

}

 

void Pre ()                                           //预处?/span>

{

                int i, j, min, b;

                //计算所需枚D的带宽的最?/span>

                maxBand = INT_MAX;                   //maxBand为所有设备带宽最大值的最?/span>

                minBand = INT_MAX;                    //minBand为所有设备带宽最值的最?/span>

                for (i=0; i<deviceNum; i++)

                {

                                if ( device[i].maxBand < maxBand )

                                                maxBand = device[i].maxBand;

                                if ( device[i].minBand < minBand )

                                                minBand = device[i].minBand;

                }

 

                //对于每个讑֤Q找到带宽大于等于某一值的最h(hun)?/span>

                for (i=0; i<deviceNum; i++)

                {

                                //band从大到小Q?/span>band相等?/span>price从小到大

                                qsort(device[i].info, device[i].manuNum, sizeof(Info), cmp);

                                device[i].minPrice.clear();

                                min = device[i].info[0].price;

                                b = device[i].info[0].band;

                                device[i].minPrice[b] = min;

                                for (j=1; j<device[i].manuNum; j++)

                                {

                                                if ( device[i].info[j].band == b )

                                                                continue;

                                                if ( device[i].info[j].price < min )

                                                {

                                                                min = device[i].info[j].price;

                                                }

                                                b = device[i].info[j].band;

                                                device[i].minPrice[b] = min;

                                }

                }             

}

 

void Solve ()

{

                Pre();

 

                int b, i, totalPrice;

                double rate, ans;

                map<int, int>::iterator it;

                ans = 0;

                start = band.find(minBand);

                end = band.find(maxBand);

                end ++;

                while ( start != end )

                {

                                b = *start;

                                start ++;

                                totalPrice = 0;

                                for (i=0; i<deviceNum; i++)

                                {

                                                //扑ֈ带宽大于{于b的最h(hun)?/span>

                                                for (it=device[i].minPrice.begin(); it!=device[i].minPrice.end(); it++)

                                                {

                                                                if ( it->first >= b )

                                                                {

                                                                                totalPrice += it->second;

                                                                                break;

                                                                }

                                                }

 

                                }

                                rate = double(b) / totalPrice;

                                if ( rate > ans )

                                                ans = rate;

                }

 

                printf("%.3f\n", ans);

}

 

int main ()

{

                int test;

                cin>>test;

                while ( test -- )

                {

                                Input ();

                                Solve ();

                }

 

                return 0;

}



ACM-Boy 2008-04-25 21:25 发表评论
]]>
PKU 3513 Let's Go to the Movieshttp://m.shnenglu.com/ACM-Boy/archive/2008/03/25/45395.htmlACM-BoyACM-BoyTue, 25 Mar 2008 15:16:00 GMThttp://m.shnenglu.com/ACM-Boy/archive/2008/03/25/45395.htmlhttp://m.shnenglu.com/ACM-Boy/comments/45395.htmlhttp://m.shnenglu.com/ACM-Boy/archive/2008/03/25/45395.html#Feedback0http://m.shnenglu.com/ACM-Boy/comments/commentRss/45395.htmlhttp://m.shnenglu.com/ACM-Boy/services/trackbacks/45395.html阅读全文

ACM-Boy 2008-03-25 23:16 发表评论
]]>
pku 1505 Copying Bookshttp://m.shnenglu.com/ACM-Boy/archive/2008/03/10/44085.htmlACM-BoyACM-BoyMon, 10 Mar 2008 07:11:00 GMThttp://m.shnenglu.com/ACM-Boy/archive/2008/03/10/44085.htmlhttp://m.shnenglu.com/ACM-Boy/comments/44085.htmlhttp://m.shnenglu.com/ACM-Boy/archive/2008/03/10/44085.html#Feedback0http://m.shnenglu.com/ACM-Boy/comments/commentRss/44085.htmlhttp://m.shnenglu.com/ACM-Boy/services/trackbacks/44085.html解题报告

 

题目来源Q?/span>

PKU 1505 Copying Books

 

法分类Q?/span>

DP

 

原文Q?/span>

Copying Books

Time Limit: 3000MS


Memory Limit: 10000K

Total Submissions: 1806


Accepted: 404

Description

Before the invention of book-printing, it was very hard to make a copy of a book. All the contents had to be re-written by hand by so called scribers. The scriber had been given a book and after several months he finished its copy. One of the most famous scribers lived in the 15th century and his name was Xaverius Endricus Remius Ontius Xendrianus (Xerox). Anyway, the work was very annoying and boring. And the only way to speed it up was to hire more scribers.

Once upon a time, there was a theater ensemble that wanted to play famous Antique Tragedies. The scripts of these plays were divided into many books and actors needed more copies of them, of course. So they hired many scribers to make copies of these books. Imagine you have m books (numbered 1, 2 ... m) that may have different number of pages (p1, p2 ... pm) and you want to make one copy of each of them. Your task is to divide these books among k scribes, k <= m. Each book can be assigned to a single scriber only, and every scriber must get a continuous sequence of books. That means, there exists an increasing succession of numbers 0 = b0 < b1 < b2, ... < bk-1 <= bk = m such that i-th scriber gets a sequence of books with numbers between bi-1+1 and bi. The time needed to make a copy of all the books is determined by the scriber who was assigned the most work. Therefore, our goal is to minimize the maximum number of pages assigned to a single scriber. Your task is to find the optimal assignment.

Input

The input consists of N cases. The first line of the input contains only positive integer N. Then follow the cases. Each case consists of exactly two lines. At the first line, there are two integers m and k, 1 <= k <= m <= 500. At the second line, there are integers p1, p2, ... pm separated by spaces. All these values are positive and less than 10000000.

Output

For each case, print exactly one line. The line must contain the input succession p1, p2, ... pm divided into exactly k parts such that the maximum sum of a single part should be as small as possible. Use the slash character ('/') to separate the parts. There must be exactly one space character between any two successive numbers and between the number and the slash.

If there is more than one solution, print the one that minimizes the work assigned to the first scriber, then to the second scriber etc. But each scriber must be assigned at least one book.

Sample Input

2

9 3

100 200 300 400 500 600 700 800 900

5 4

100 100 100 100 100

Sample Output

100 200 300 400 500 / 600 700 / 800 900

100 / 100 / 100 / 100 100

Source

Central Europe 1998

 

 

中文描述Q?/span>

题目大意是给?/span>mQ?/span>1…mQ本书,每本书有Pm,?/span>kQ?/span>k<=mQ个员工来复印这些书。每本书只能分配l一个员工来复印Qƈ且每个员工必dCD连l的书籍Q每个员工复印的旉取决于所复印书籍的总页数。让你给出相应的分配Q得分配给员工的书c页数的最大值尽量小。注意,如果有多U分配的Ҏ(gu)Q得第一个员工的书籍|量,其次是第二个、第三个……以此cL?/span>

 

题目分析Q?/span>

我们可以从后往前推Q最后一个员工,也就是第k个员工,他至要复印W?/span>m本书Q至多可以复印第k本到W?/span>m本(因ؓ(f)臛_要分配给?/span>k-1个员工每Z本书Q。假设,W?/span>k名员工复制第iQ?/span>k<=i<=mQ本书到W?/span>m本书Q那么,所有员工复Cc的最时间就为第k名员工所需的时间以?qing)?/span>k-1名员工复制前i-1本书所需最时间的较大的那个时间。这P问题的规模就?/span>k个员工复?/span>m本书减小C(jin)k-1个员工复?/span>i-1本书Q而且求解q程中会(x)不断遇到?/span>a个员工复印前b本书的最时间。ؓ(f)?jin)减问题的规模以?qing)记录重复子问题的解,可以用DP?/span>

但仅仅算出最时间的不够的,q要l出分配的方案,q个E微有点J琐。因为题目中_(d)如果有多U最优的分配Ҏ(gu)Q应该让前面的员工分配的|量。那么,可以从后推,在当前的员工所复印的书c页数没有超q最大页数的情况下,让其复印的页数最大化。如果超q了(jin)最大页敎ͼ把q本书分配给前一名员工。最后再按顺序将分配l果输出出来?/span>

 

代码Q?/span>

#include <cstdio>

#include <climits>

#include <cstring>

 

const int MAX = 505;

int book[MAX];

__int64 total[MAX];                        //1~n本书的页?/span>

int k, m;

__int64 f[MAX][MAX];                  //f[i][j] = k 表示?/span>i个h复制?/span>j本书所需最时间是k

__int64 max;

void Input ()

{

                scanf("%d%d", &m, &k);

                int i;

                for (i=1; i<=m; i++)

                                scanf("%d", &book[i]);

}

 

__int64 Sum (int s, int e)                                               //W?/span>s本书到第e本书的总页?/span>

{

                return (total[e] - total[s-1]);

}

 

__int64 Max (__int64 a, __int64 b)

{

                return ( a>b?a:b );

}

 

__int64 Min (int x, int y)                                //?/span>x个h复制?/span>y本书所需的最时?/span>        x<=y

{

//考虑Ҏ(gu)情况

                if ( f[x][y] != -1 )

                                return f[x][y];

                if ( y == 0 )

                                return ( f[x][y] = 0 );

                if ( x == 0 )

                                return ( f[x][y] = INT_MAX );

 

                int i;

                __int64 temp;

                f[x][y] = INT_MAX;

                for (i=x-1; i<y; i++)

                {

//W?/span>x个h复制W?/span>i+1到第y本书与前x-1个h复制?/span>i本书的时间较大的旉

                                temp = Max( Min(x-1, i), Sum(i+1, y) );                 

                                if ( temp < f[x][y] )

                                {

                                                f[x][y] = temp;

                                }

                }

                return f[x][y];

}

 

void Output ()

{

                int i, p;

                __int64 temp;

                int slash[MAX];

                max = f[k][m];

                memset(slash, 0, sizeof(slash));

                temp = 0;

                p = k;

                for (i=m; i>0; i--)

                {

                                //让后面的员工量复印最多的书籍

                                if ( temp + book[i] > max || i < p )

                                {

                                                slash[i] = 1;

                                                temp = book[i];

                                                p --;

                                }

                                else

                                {

                                                temp += book[i];

                                }

                }

 

                for (i=1; i<=m; i++)

                {

                                printf("%d", book[i]);

                                if ( slash[i] == 1 )

                                                printf(" / ");

                                else if ( i != m )

                                                printf(" ");

                }

                printf("\n");

}

 

void Solve ()

{

                int i, j;

                //预处理书c页数的?/span>

                total[0] = 0;

                for (i=1; i<=m; i++)

                                total[i] = total[i-1] + book[i];

 

                memset(f, -1, sizeof(f));

               

                Min(k, m);

               

                Output();

}

 

int main ()

{

                int test;

                scanf("%d", &test);

                while ( test-- )

                {

                                Input ();

                                Solve ();

                }

 

                return 0;

}

 

 

E序分析与心(j)得:(x)

旉复杂?/span>O(n2)Q空间复杂度O(n2)?/span>

在用记忆化搜索解?/span>DP问题Ӟ往往比较W合人的思维Q容易想到模型,~程比较单。在解题q程中,除了(jin)可以按照常理着推,也可以尝试逆向思维Q从最后的状态倒着推,q样可以佉K题想得更加透彻Q有比较好的效果?/span>



ACM-Boy 2008-03-10 15:11 发表评论
]]>
PKU 2181 Jumping Cowshttp://m.shnenglu.com/ACM-Boy/archive/2008/02/02/42409.htmlACM-BoyACM-BoySat, 02 Feb 2008 13:41:00 GMThttp://m.shnenglu.com/ACM-Boy/archive/2008/02/02/42409.htmlhttp://m.shnenglu.com/ACM-Boy/comments/42409.htmlhttp://m.shnenglu.com/ACM-Boy/archive/2008/02/02/42409.html#Feedback0http://m.shnenglu.com/ACM-Boy/comments/commentRss/42409.htmlhttp://m.shnenglu.com/ACM-Boy/services/trackbacks/42409.html    l你n个药的序列,牛从旉1开始吃药,在奇数时间吃药可以增加弹跛_Q在偶数旉吃药则会(x)减少弹蟩力。在某一旉Q你可以跌一些药Q但一旦吃q某U药Q你׃能在选前面的药了(jin)。问你某一个吃药的序列Q牛最l的弹蟩力最大?br>
思\Q?br>    虽然题目不难Q但思考题目的q程十分有意思。对于某U药Q共?中状态:(x)在奇数时间吃、在奇数旉不吃、在偶数旉吃以?qing)在偶数旉不吃。关键在于这4U状态之间的转移。因为如果蟩q某U药是不需要花Ҏ(gu)间的Q所以在?ơ的吃药旉内,旉相当于是?rn)止的,一直维持在W?ơ吃药的旉D内?br>    所以可用一数组max[i][2][2]表示状态,WiU药在奇/偶时间段内吃/不吃。可得状态{Ud表示为:(x)
    max[i][0][0] = Max (max[i-1][0][0], max[i-1][0][1]);
    max[i][0][1] = Max (max[i-1][1][0], max[i-1][1][1]) - high[i];
    max[i][1][0] = Max (max[i-1][1][0], max[i-1][1][1]);
    max[i][1][1] = Max (max[i-1][0][0], max[i-1][0][1]) + high[i];

代码Q?br>
#include <iostream>
using namespace std;

const int MAX = 150005;
int high[MAX];
int max[MAX][2][2];
int n;

void Input ()
{
    scanf("%d", &n);
    int i;
    for (i=1; i<=n; i++)
        scanf("%d", &high[i]);

}

int Max (int a, int b)
{
    return ( a>b?a:b );
}

void Solve ()
{
    int i;
    for (i=1; i<=n; i++)
    {
        max[i][0][0] = Max (max[i-1][0][0], max[i-1][0][1]);
        max[i][0][1] = Max (max[i-1][1][0], max[i-1][1][1]) - high[i];
        max[i][1][0] = Max (max[i-1][1][0], max[i-1][1][1]);
        max[i][1][1] = Max (max[i-1][0][0], max[i-1][0][1]) + high[i];
    }
    printf("%d\n", Max ( Max(max[n][0][0], max[n][0][1]), Max(max[n][1][0], max[n][1][1])) );
}

int main ()
{
    Input ();
    Solve ();

    return 0;
}


ACM-Boy 2008-02-02 21:41 发表评论
]]>
PKU 2559 Largest Rectangle in a Histogramhttp://m.shnenglu.com/ACM-Boy/archive/2008/02/01/42366.htmlACM-BoyACM-BoyFri, 01 Feb 2008 11:34:00 GMThttp://m.shnenglu.com/ACM-Boy/archive/2008/02/01/42366.htmlhttp://m.shnenglu.com/ACM-Boy/comments/42366.htmlhttp://m.shnenglu.com/ACM-Boy/archive/2008/02/01/42366.html#Feedback0http://m.shnenglu.com/ACM-Boy/comments/commentRss/42366.htmlhttp://m.shnenglu.com/ACM-Boy/services/trackbacks/42366.html题目大意Q?/span>
    l定n个连l的长度?的矩形的高度hQ?<=n<=100000Q?<=hi<=1000000000Q,问你其中能构成的最大矩形的面积是多?/span>

思\Q?/span>
    很显?dng)用DP。但关键是怎样表示状态,一开始想用一个二l数lmin[][]表示从i~j的最高度,面积q于min[i][j]*(j-i+1)。但很不q,Ҏ(gu)题目l定的n的范_(d)q个二维数组Ҏ(gu)无法创徏?(
    后来从论坛上得到提示Q因为对于图中的某个面积最大的矩ŞQ必然有一个最低的高度h[k]Q即矩Ş的高{于h[k]Q以Wk块矩形的高度Q最左边可以到达q个矩Ş的左边,最双可以到达q个矩Ş的右辏V所以,可以以每块矩形进行扩展,求出最左边和最双Q即两边的高度都大于{于q块的高度)(j)Q得出面Us[i]Q这样就可求出最大的s[i]?jin)?/span>

代码Q?/span>

#include <cstdio>

const int MAX = 100005;
__int64 h[MAX];
__int64 left[MAX], right[MAX];        //left[i] = j表示Wi个矩形以它的高度到达最左边的下?/span>
int n;

bool Input ()
{
    scanf("%d", &n);
    if ( n == 0 )
        return false;
    int i;
    for (i=1; i<=n; i++)
        scanf("%I64d", &h[i]);
    h[0] = h[n+1] = -1;
    return true;
}

void Solve ()
{
    int i;
    __int64 temp, max;
    for (i=1; i<=n; i++)
    {
        left[i] = right[i] = i;
    }

    for (i=1; i<=n; i++)
    {
        while ( h[left[i]-1] >= h[i] )
            left[i] = left[left[i]-1];
    }
    for (i=n; i>0; i--)
    {
        while ( h[right[i]+1] >= h[i] )
            right[i] = right[right[i]+1];
    }

    max = 0;
    for (i=1; i<=n; i++)
    {
        temp = h[i] * (right[i] - left[i] + 1);
        if ( temp > max )
            max = temp;
    }

    printf("%I64d\n", max);
}

int main ()
{
    while ( Input() )
    {
        Solve();
    }

    return 0;
}




ACM-Boy 2008-02-01 19:34 发表评论
]]>
pku 3486 Computershttp://m.shnenglu.com/ACM-Boy/archive/2008/01/28/42029.htmlACM-BoyACM-BoyMon, 28 Jan 2008 06:45:00 GMThttp://m.shnenglu.com/ACM-Boy/archive/2008/01/28/42029.htmlhttp://m.shnenglu.com/ACM-Boy/comments/42029.htmlhttp://m.shnenglu.com/ACM-Boy/archive/2008/01/28/42029.html#Feedback0http://m.shnenglu.com/ACM-Boy/comments/commentRss/42029.htmlhttp://m.shnenglu.com/ACM-Boy/services/trackbacks/42029.html题目大意Q?/p>     l定一个时间期间nQ电(sh)脑的hcQ以?qing)?sh)脑的l修费用m(y,z)Q第y台电(sh)脑从yq用到第zqȝl修费用Q。让你求出在期限n中用电(sh)脑的最低费用?br>
思\Q?br>    Z(jin)让总费用最低,你必M?gu)L(fng)决策Q假设你正在使用某一台电(sh)脑已用到yq_(d)你y+1q是l箋(hu)用这台电(sh)脑,q是重新买第y+1台电(sh)脑(注意Q这里的y+1是指输入中的Wy+1行电(sh)脑,而不是指你已购买?jin)y+1台电(sh)脑,因ؓ(f)yq只能买输入中的Wy行电(sh)脑,Z(jin)不生؜淆,电(sh)脑用~号表示Q。显?dng)某一阶段的最优解q不能一定导致全局的最优解Q所以肯定不能用贪心(j)?br>    我们从最后的情况来考虑Q最后必然是某一个编号ؓ(f)y的电(sh)脑,从第yq用到Wnq_(d)而前面的1~y-1q_(d)自己只可能购买编号ؓ(f)1~y-1的电(sh)脑用到y-1q。这P问题的范围就减小?jin),从编号?f)1~n的电(sh)脑用nq_(d)降低C(jin)~号?~y-1的电(sh)脑用y-1q。经分析Q可推出递推式:(x)
    F[n] = min { F[i] + c + m[i+1][n] | 0<=i<=n-1 }
F[n]表示n台电(sh)脑用nq的最低费?br>
代码Q?br>
#include <cstdio>
#include <climits>
#include <cstring>

const int MAX = 1005;
int n, c;
int mend[MAX][MAX];
int f[MAX];
int cost;

bool Input ()
{
    if ( scanf("%d", &c) == EOF )
        return false;
    scanf("%d", &n);
    int i, j;
    for (i=1; i<=n; i++)
    {
        for (j=i; j<=n; j++)
            scanf("%d", &mend[i][j]);
    }
    return true;
}


void Solve ()
{
    int i, j;
    memset(f, 0, sizeof(f));
    for (i=1; i<=n; i++)
    {
        f[i] = INT_MAX;
        for (j=0; j<i; j++)
        {
            if ( f[j] + mend[j+1][i] + c < f[i] )
                f[i] = f[j] + mend[j+1][i] + c;
        }
    }
    printf("%d\n", f[n]);
}

int main ()
{
    while ( Input() )
    {
        Solve ();
    }

    return 0;
}


ACM-Boy 2008-01-28 14:45 发表评论
]]>
PKU 1019 Number Sequencehttp://m.shnenglu.com/ACM-Boy/archive/2008/01/19/41474.htmlACM-BoyACM-BoySat, 19 Jan 2008 08:46:00 GMThttp://m.shnenglu.com/ACM-Boy/archive/2008/01/19/41474.htmlhttp://m.shnenglu.com/ACM-Boy/comments/41474.htmlhttp://m.shnenglu.com/ACM-Boy/archive/2008/01/19/41474.html#Feedback0http://m.shnenglu.com/ACM-Boy/comments/commentRss/41474.htmlhttp://m.shnenglu.com/ACM-Boy/services/trackbacks/41474.html题意Q?br>     是有这样一个序列:(x)1 12 123 1234 12345 .....Q输入序列的下标Q让你算?gu)序列所在下标的字符

思\Q?br>     一开始想用字W串模拟来做Q结果TLE。后来看?jin)discussQ又想了(jin)一下,发现可以按规律将序列分成几段Q然后再在每D中查找。具体做法是Q先按序? 中数字的位数来分Q?12123...123456789是一D,1..10 1..11 1..12 ... 1..99是一D,1..100 ... 1..999是一D,以此cL。确定了(jin)是在上面的哪一D以后,再按cM的思想定q个下标是在哪个12345...n的序列,最后判断是在其中哪个数字的 哪一位?br>
代码Q?br> #include <iostream>
#include <cmath>
using namespace std;

const long long a[] = {0, 45, 9045, 1395495, 189414495, 2147483648};            //112123...9, 11231234...99, ... 的位?br> const long long b[] = {1, 11, 192, 2893, 38894, 488895, 5888896};                //1, 1234...10, 1234...100, ...的位?br>
int digit (int n)
{
    int ans = 1;
    while ( n / 10 != 0 )
    {
          n /= 10;
          ans ++;
    }
    return ans;
}

char Pos (int n, long long index)      //?234...n中找C标ؓ(f)index的字W?br> {
     long long i, j;
     long long pos = 0;
     for (i=1; i<=n; i++)
     {
         pos += digit(i);
         if ( pos >= index )
            break;
     }
    
     pos -= digit(i);               //定位在i?br>      j = digit(i) - (index - pos);
     //if ( j == digit(i) - 1 )
     //   cout<<endl;
     while ( j > 0 )
     {
           i /= 10;
           j --;
     }

     return (i % 10) + '0';
}


char Find (long long pos)
{
     long long p, t;
     int index = 0;
     int temp;
     while ( a[index] < pos )
     {
           index ++;
     }
     p = a[index - 1];
    
     p += b[index - 1];
     temp = int(pow(10.0, index-1));
     t = b[index - 1] + index;
     while ( p < pos )
     {
           p += t;
           t += index;
           temp ++;
     }
    
     p -= t - index;
    
     return Pos(temp, pos-p);
}

int main ()
{
    int test;
    long long i;
    cin>>test
    while ( test-- )
    {
          cin>>i;
          cout<<Find(i)<<endl;
    }

    return 0;


ACM-Boy 2008-01-19 16:46 发表评论
]]>
PKU2975 Nimhttp://m.shnenglu.com/ACM-Boy/archive/2007/12/07/38025.htmlACM-BoyACM-BoyFri, 07 Dec 2007 13:41:00 GMThttp://m.shnenglu.com/ACM-Boy/archive/2007/12/07/38025.htmlhttp://m.shnenglu.com/ACM-Boy/comments/38025.htmlhttp://m.shnenglu.com/ACM-Boy/archive/2007/12/07/38025.html#Feedback3http://m.shnenglu.com/ACM-Boy/comments/commentRss/38025.htmlhttp://m.shnenglu.com/ACM-Boy/services/trackbacks/38025.html    因ؓ(f)每次只能从一个堆中取矛_Q所以只要对于每个堆iQ先求出其他所有堆的异或和tempQ再?~Ki-1与这个异或和再进行异或是否ؓ(f)0Q只要ؓ(f)0得CU胜利的Ҏ(gu)。自己先是想枚D0~Ki-1Q与tempq行异或。后来感觉没有必要,只要Ki>temp可以了(jin)Q因从堆i中取出x个石子,Ki-x异或temp==0 <==> Ki-x==tempQ只要Ki>tempQ就存在Ki-x==temp?br>
#include <cstdio>

#define PILE 1001

__int64 stone[PILE], test;       //test为所有石子数的异或和
int piles;

bool Input ()
{
    scanf("%d", &piles);
    if ( piles == 0 )
        return false;
   
    int i;
    for (i=0; i<piles; i++)
        scanf("%I64d", &stone[i]);
    return true;
}

void Solve ()
{
    int i, ans;
    __int64 temp;
    test = 0;
    ans = 0;
    for (i=0; i<piles; i++)
        test ^= stone[i];
   
    if ( test != 0 )
    {
        for (i=0; i<piles; i++)
        {
            temp = test ^ stone[i];      //再与stone[i]做一ơ异或,相当于除stone[i]对其他所有堆的石子进行异?br>
            if ( stone[i] > temp )
                ans++;
        }
    }
    printf("%d\n", ans);
}

int main ()
{
    while ( Input() )
    {
        Solve();
    }
   
    return 0;
}




ACM-Boy 2007-12-07 21:41 发表评论
]]>
PKU2907 Collecting Beepershttp://m.shnenglu.com/ACM-Boy/archive/2007/12/07/38019.htmlACM-BoyACM-BoyFri, 07 Dec 2007 11:31:00 GMThttp://m.shnenglu.com/ACM-Boy/archive/2007/12/07/38019.htmlhttp://m.shnenglu.com/ACM-Boy/comments/38019.htmlhttp://m.shnenglu.com/ACM-Boy/archive/2007/12/07/38019.html#Feedback1http://m.shnenglu.com/ACM-Boy/comments/commentRss/38019.htmlhttp://m.shnenglu.com/ACM-Boy/services/trackbacks/38019.html    因ؓ(f)地图最大只?0×20Q而beeper最多也只有10个,所以可以考虑用深搜,扑ֈ所有可能\径,在其中加一些简单的减枝可以了(jin)。v初以Z(x)时Q可最后还?ms。:(x)Q?br>

Source Code

Problem: 2907
User: QuXiao
Memory: 176K
Time: 0MS
Language: C++
Result: Accepted
  • Source Code
  • #include <iostream>
    #include <climits>
    using namespace std;

    struct Point
    {
    int x, y;
    };

    int num, X, Y;
    Point start, beeper[15];
    int shortest;
    int visited[15];


    int Length (Point p1, Point p2)
    {
    return abs(p1.x - p2.x) + abs(p1.y - p2.y);
    }

    void Input ()
    {
    int i;
    cin>>X>>Y;
    cin>>start.x>>start.y;
    cin>>num;
    for (i=0; i<num; i++)
    cin>>beeper[i].x>>beeper[i].y;
    }

    void DFS (int cur, int len, int n)
    {
    if ( n == num )
    {
    int t = Length(beeper[cur], start);
    if ( len + t < shortest )
    shortest = len + t;
    }
    else if ( len < shortest )
    {
    int i;
    for (i=0; i<num; i++)
    {
    if ( visited[i] == 0 )
    {
    visited[i] = 1;
    DFS (i, len+Length(beeper[cur], beeper[i]), n+1);
    visited[i] = 0;
    }
    }
    }
    }


    void Solve ()
    {
    int i, t;
    shortest = INT_MAX;
    memset(visited, 0, sizeof(visited));
    for (i=0; i<num; i++)
    {
    t = Length(beeper[i], start);
    visited[i] = 1;
    DFS (i, t, 1);
    visited[i] = 0;
    }
    cout<<"The shortest path has length "<<shortest<<endl;
    }

    int main ()
    {
    int test;
    cin>>test;
    while ( test-- )
    {
    Input ();
    Solve ();
    }

    return 0;
    }





ACM-Boy 2007-12-07 19:31 发表评论
]]>
þþþƷƵѹۿ| þŷ޹ۺ| þþþëƬ| þ66͵Ʒ9| ˺ݺۺϾþ| ޾ƷþþþAV鶹| þþþĻɫ| avԾþþþa| ۺϾþü| 츾޾þĻ| þ99Ʒþþþþ9 | 77777ҹþö| þþ99ƷƬĻ| ˾þۺϾƷAVר| þ99Ʒþ99| ݺɫݺɫۺϾþ | þ99ù龫Ʒ66| þùƷ99Ʒ987| պŷۺϾþӰԺDs| þ97Ʒþþþþþò| ձŷþþþѲ| պŮ18վþþƷ| þòӰ| þþƷ99þ˿| Ʒþþþþ| þþþavר| ͵ٸþþþþþþ| պþþþƷӰԺҳ| ھƷþù½| þþþþAVר| պƷþĻ| þרƷ| þþȹ͵ۺ| Ʒպþ| ݺɫþþۺ| ާѡþþþƷ| ŷһþþƷ| ĻȾþþþþþ| ձþþþĻ| 99999þþþþ| þþƵ|