hdu 1421 搬寝室 dp 类似背包

来源:互联网 发布:苏打饼干 知乎 编辑:程序博客网 时间:2024/06/06 02:47
//这道题的意思很明显呐,状态想出来了//dp[i][j]表示在前i件物品中挑选j对物品的最小皮料值//但是想着01背包的样子写,结果wa啦//然后思索了很久之后,发现自己就状态想出来了,转移方程一塌糊涂//dp[i][j]表示在前i件物品中挑选j对物品的最小皮料值//最重要的是要进行排序,升序排列或者降序排列,这样连续取俩相//邻的所得到的差的平方一定是最小的,因为差值最小//分两种情况讨论://1)如果当前的i件物品正好可以凑成j对//dp[i][j] = dp[i-2][j-1]+get_value(i,i-1);//2)//dp[i][j] = min(dp[i-2][j-1]+get_value(i,i-1),dp[i-1][j]);//其中dp[i-1][j]表示不选第i个物品能凑成j对的最小的疲劳值//dp[i-2][j]表示选第i个物品(那它一定得和i-1配对,这样才能差//值最小)能凑成j-1对所能得到的最小的疲劳值////注释的代码还是之前错的思路,还是留着给自己一个警醒吧//哎,继续练吧//const int inf = 0x3f3f3f3f;//const int maxn = 2008;//ll dp[maxn];//ll a[maxn];//int n,k;////void init(){//for (int i=1;i<=n;i++)//scanf("%I64d",&a[i]);//memset(dp,inf,sizeof(dp));//dp[0] = 0;//}////ll value(int i,int j){//return (a[i]-a[j]) * (a[i]-a[j]);//}//////void solve(){//sort(a+1,a+1+n);//for (int i=1;i<=n;i++){//for (int j=min(i,2*k);j>=2;j--){//dp[j] =min(dp[j],dp[j-2]+value(j/2,j/2+1));//}//}////for (int i=0;i<=n;i++)////printf("%I64d ",a[i]);////puts("");//printf("%I64d\n",dp[2*k]);//}////int main() {//    freopen("G:\\Code\\1.txt","r",stdin);//while(scanf("%d%d",&n,&k)!=EOF){//init();//solve();//}//return 0;//}#include <algorithm>#include <bitset>#include <cassert>#include <cctype>#include <cfloat>#include <climits>#include <cmath>#include <complex>#include <cstdio>#include <cstdlib>#include <cstring>#include <ctime>#include <deque>#include <functional>#include <iostream>#include <list>#include <map>#include <numeric>#include <queue>#include <set>#include <stack>#include <vector>#define ceil(a,b) (((a)+(b)-1)/(b))#define endl '\n'#define gcd __gcd#define highBit(x) (1ULL<<(63-__builtin_clzll(x)))#define popCount __builtin_popcountlltypedef long long ll;using namespace std;const int MOD = 1000000007;const long double PI = acos(-1.L);const int inf = 0x3f3f3f3f;template<class T> inline T lcm(const T& a, const T& b) { return a/gcd(a, b)*b; }template<class T> inline T lowBit(const T& x) { return x&-x; }template<class T> inline T maximize(T& a, const T& b) { return a=a<b?b:a; }template<class T> inline T minimize(T& a, const T& b) { return a=a<b?a:b; }const int maxn = 2048;int dp[maxn][maxn];int a[maxn];int n,k;int cmp(int a,int b){return a<b;}int get_value(int i,int j){return (a[i]-a[j]) * (a[i]-a[j]);}void init(){for (int i=1;i<=n;i++)scanf("%d",&a[i]);a[0] = 0;//for (int i=1;i<=n;i++)//printf("%d ",a[i]);memset(dp,0,sizeof(inf));sort(a+1,a+1+n,cmp);//for (int i=0;i<n;i++)//dp[0][i]=0;dp[0][0]=0;}void print(){for (int i=1;i<=n;i++){for (int j=0;j<=k;j++)printf("%d ",dp[i][j]);puts("");}}void solve(){for (int i=2;i<=n;i++){int f = i/2;for (int j=1;j<=f;j++){if (i==2*j)dp[i][j] = dp[i-2][j-1]+get_value(i,i-1);else dp[i][j] = min(dp[i-2][j-1]+get_value(i,i-1),dp[i-1][j]);}}printf("%d\n",dp[n][k]);//print();}int main() {   // freopen("G:\\Code\\1.txt","r",stdin);while(scanf("%d%d",&n,&k)!=EOF){init();solve();}return 0;}


0 0
原创粉丝点击