HDU 4395 D-mail
2016-05-13 22:19
531 查看
这就是多校赛的水题了。。。
简单dp放大10000倍,然后左移200000(0.1 *200 *10000)就可以了。。
然后下面是bitset版的,感觉bitset是一个很好的模拟工具。。。
真是又快又好。。。。
简单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; }
真是又快又好。。。。
相关文章推荐
- 详解Android应用中屏幕尺寸的获取及dp和px值的转换
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- LFC1.0.0 版本发布
- Android dpi,dip,dp的概念以及屏幕适配
- Android px、dp、sp之间相互转换
- HP data protector软件学习1--基本角色与基本工作流程
- HP data protector软件学习2--软件组成与界面介绍
- android中像素单位dp、px、pt、sp的比较
- Android对px和dip进行尺寸转换的方法
- 【HDU 5366】The mook jong 详解
- 【HDU 2136】Largest prime factor 详细图解
- 【HDU 1568】Fibonacci 数学公式 详解
- Android根据分辨率进行单位转换-(dp,sp转像素px)
- android 尺寸 dp,sp,px,dip,pt详解
- DP问题各种模型的状态转移方程
- HDU 1568
- HDU1290
- POJ-1695-Magazine Delivery-dp
- nyoj-1216-整理图书-dp