HDU 4395 D-mail

来源:互联网 发布:oppo系统优化 编辑:程序博客网 时间:2024/05/29 14:56

这就是多校赛的水题了。。。

简单dp放大10000倍,然后左移200000(0.1 *200 *10000)就可以了。。

#include <cstdio>#include <iostream>#include <string>#include <cstring>#include <algorithm>#include <bitset>using namespace std;const int M = 210;const int N = 220000;const double eps = 1e-8;int a[M];int dp[N];int main(){    int T;    scanf("%d", &T);    while(T --)    {        int num;        double testfin;        scanf("%lf%d", &testfin , &num);        int fin;        if(testfin > 0)        {            fin = testfin * 10000 + eps;        }        else        {            fin = testfin * 10000 - eps;        }        double test;        for(int i = 1 ; i <= num ; ++ i)        {            scanf("%lf", &test);            if(test > 0)            {                a[i] = test * 10000 + eps;            }            else            {                a[i] = test * 10000 - eps;            }        }        sort(a + 1 , a + num + 1);        memset(dp , 0 , sizeof(dp));        dp[200000] = 1;        for(int i = 1 ; i <= num ; ++ i)        {            if(a[i] > 0)            {                for(int j = 220000 - 1 ; j >= a[i] ; -- j)                {                    if(dp[j - a[i]])                    {                        dp[j] = 1;                    }                }            }            else            {                for(int j = -a[i]; j <= 220000 - 1; ++ j)                {                    if(dp[j])                    {                        dp[j + a[i]] = 1;                    }                }            }        }        int left;        int right;        for(left = fin + 200000, right = fin + 200000 ; ; left -- , right ++)        {            if(dp[left] && left >= 0)            {                printf("%.4lf\n", (left - 200000.0) / 10000);                break;            }            else if(dp[right] && right < 220000)            {                printf("%.4lf\n", (right - 200000.0) / 10000);                break;            }        }    }    return 0;}

然后下面是bitset版的,感觉bitset是一个很好的模拟工具。。。

#include <cstdio>#include <iostream>#include <cstring>#include <string>#include <algorithm>#include <bitset>using namespace std;const double eps = 1e-8;const int N = 210;int a[N];bitset<220000>dp;int main(){    int T;    scanf("%d", &T);    while(T --)    {        int num;        double testfin;        int fin;        scanf("%lf%d", &testfin, &num);        if(testfin > 0)        {            fin = testfin * 10000 + eps;        }        else        {            fin = testfin * 10000 - eps;        }        double test;        for(int i = 1 ; i <= num ; ++ i)        {            scanf("%lf", &test);            if(test > 0)            {                a[i] = test * 10000 + eps;            }            else            {                a[i] = test * 10000 - eps;            }        }        sort(a + 1 ,a + num + 1);        dp.reset();        dp.set(200000);        for(int i = 1 ;i <= num ; ++ i)        {            if(a[i] > 0)            {                dp = dp | (dp << a[i]);            }            else            {                dp = dp | (dp >> (- a[i]));            }        }        int left, right;        for(left = 200000 + fin, right = 200000 + fin ; ; left-- ,right ++)        {            if(left >= 0 && dp[left])            {                printf("%.4lf\n", (left - 200000.0) / 10000);                break;            }            else if(right < 220000 && dp[right])            {                printf("%.4lf\n", (right - 200000.0) / 10000);                break;            }        }    }    return 0;}

真是又快又好。。。。

0 0
原创粉丝点击