zoukankan      html  css  js  c++  java
  • 多米诺骨牌

    题目传送门

    结合两篇题解:

    1
    2

    有了我这篇博客。
    主要思路是题解1。初始时先将所有骨牌翻转成上边的点数大,假设这时上下点数之差为(tot),此时翻转的骨牌数记为(base)。那么现在要再次翻转骨牌使得差值变小,假设第(i)张骨牌上下差值为(k),那么将这张骨牌翻转过来差值会减小(2*k)。明显最终差值会减到负值。当差值减到0时是最优答案。将减小的差值统一加上(tot),那么差值越接近(tot),答案越优。取所有差值减去(tot)的绝对值最小的一个便是答案。要注意减小的差值可能有0的情况(第10个点)。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    const int N = 1005;
    int dp[N][N*6],w[N],v[N],n,tot,base,tot1,ansp,ans=2147483647;
    bool vs[N][N*6];
    int main()
    {
    	ansp=2147483647;
    	int x,y;
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d%d",&x,&y);
    		tot1+=x-y;
    		if(x>y)
    		{
    			v[i]=2*(x-y); w[i]=1;
    			tot+=x-y;
    		}
    		if(y>x)
    		{
    			v[i]=2*(y-x); w[i]=-1;
    			tot+=y-x;
    			base++;
    		}
    	}
    	for(int i=1;i<=n;i++)
    	 for(int j=0;j<=tot+tot;j++)
    	 {
    	 	dp[i][j]=dp[i-1][j];
    	 	vs[i][j]=vs[i-1][j];
    	 	if(vs[i-1][j-v[i]]||j-v[i]==0)
    	 	{
    	 		if(!vs[i][j])
    	 		{
    	 			dp[i][j]=dp[i-1][j-v[i]]+w[i];
    	 			vs[i][j]=1;
    	 		}
    	 		else dp[i][j]=min(dp[i][j],dp[i-1][j-v[i]]+w[i]);
    	 	}
    	 }
    	for(int i=0;i<=tot+tot;i++)
    	if(vs[n][i])
    	{
    		if(abs(i-tot)==ans) ansp=min(ansp,dp[n][i]);
    		if(abs(i-tot)<ans) ans=abs(i-tot),ansp=dp[n][i];
    	}
    	printf("%d
    ",ansp+base);
    	return 0;
    } 
    /*
    2
    3 2
    2 2
    */
    

    最开始的思路和第二篇博客里的思路一一样,但这种思路是不行的。加入当前枚举到((i,j)),有一个答案为(a),一个答案为(-a),无法判断在以后的转移中那个更优。
    思路二值得借鉴,但是没写。

  • 相关阅读:
    python处理url中的中文编码,以及其他编码问题
    深度学习与神经网络
    Windows下为64位的python3.4.3安装numpy
    TOP 10开源的推荐系统简介
    遗传算法
    java调用c++生成的动态和静态库时遇到的问题
    java程序(一)----HashMap同时获取键值
    Deep Learning In NLP 神经网络与词向量
    word2vec使用说明
    Spring入门_02_属性注入
  • 原文地址:https://www.cnblogs.com/karryW/p/11385708.html
Copyright © 2011-2022 走看看