Climber.pI的OI之路

Through the darkest dark,may we see the light.

USACO 4.1.1 Nuggets

重启usaco.

抽象出模型,可以发现是一个简单的完全背包问题,复杂度O(N^2+VN).需要考虑几种特殊情况:
(1)无解
当且仅当n个数中有一个数为1.
(2)惟一解
需要确定的是体积v的最大值.题解中是最大的两个数的最小公倍数,程序中使用最大数的平方,证明方法不知.
(3)无限解
n个数不互质

 1/*
 2ID: liuyupa1
 3PROG: nuggets
 4LANG: C++
 5*/

 6#include<stdio.h>
 7int w[15= {0}, f[66000= {0};
 8int p[] = {2357111317192329313741434753596167717379838997101103107109113127131137139149151157163167173179181191193197199211223227229233239241251};
 9void swap(int *x, int *y){
10    int k = *x; *= *y; *= k;
11}

12int max(int x, int y){
13    return x>? x : y;
14}

15int main(){
16    FILE *fin, *fout;
17    fin = fopen("nuggets.in""r");
18    fout = fopen("nuggets.out""w");
19    int n, i, j;
20    fscanf(fin, "%d"&n);
21    for (i = 1; i <= n; i++) fscanf(fin, "%d"&w[i]);
22    for (j = 0; j < 54; j++){
23        int t = 0;
24            for (i = 1; i <= n; i++)
25            if (w[i] % p[j] == 0) t++;
26        if (t == n) {
27            fprintf(fout, "0\n", p[j]);
28            return 0;
29        }

30    }

31    for (i = 1; i < n; i++)
32        for (j = i+1; j <= n; j++)
33            if (w[i] > w[j]) swap(&w[i], &w[j]);
34    if (w[1== 1){
35        fprintf(fout, "0\n", p[j]);
36        return 0;
37    }

38    for (i = 1; i <= n; i++)
39        for (j = 0; j <= w[n]*w[n]; j++)
40            if (j-w[i] >= 0)
41                f[j] = max(f[j], f[j-w[i]]+w[i]);
42    i = w[n-1]*w[n];
43    while (i > -1 && f[i] == i) i--;
44    fprintf(fout, "%d\n", i);
45    return 0;
46}

47

posted on 2010-10-19 17:05 Climber.pI 阅读(289) 评论(0)  编辑 收藏 引用 所属分类: 动态规划


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理