您的位置:首页 > 大数据 > 人工智能

HDU 4395 D-mail

2016-05-13 22:19 531 查看
这就是多校赛的水题了。。。

简单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
;
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
;
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;
}


真是又快又好。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hdu 多校 dp